恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

Flipper Zero 上的 Doom 移植版:doom-flipper-zero 射线投射引擎原理与 .fap 安装实战

  • 首页
  • 资讯中心
  • /
  • Flipper Zero 上的 Doom 移植版:doom-flipper-zero 射线投射引擎原理与 .fap 安装实战

相关资讯

DCT加速分形图像压缩:从原理到Matlab实现的快速编码路线 2026/9/14 15:29:02
用Logistic回归做时间序列预测的Matlab实战指南 2026/9/14 15:29:02
Backstage Catalog Model 深度解析:实体类型、引用与校验体系 2026/9/14 15:29:02

最新资讯

基于EKF的锂电池SOC估计优化与MATLAB实现
Vue 3 实战进阶:10个避免踩坑的高效技巧与性能优化指南
PentestGPT 生产加固实践:可复现基准、证据溯源与失败结算机制的源码级解析
2026数据治理平台选型指南:十家厂商深度评测与避坑建议
基于YOLOv8的麻将识别系统开发与实践
跟着国家规划定学习方向:从选赛道到落地行动路线图

今日推荐

ASP+Access库存管理系统源码部署与IIS配置实战指南
基于SSM框架的毕业季旧物分类处理系统设计与实现
MATLAB FFT频谱仿真:从DFT原理到参数设置与窗函数选择

本周热门

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化
Flutter应用改名全指南:从Android到iOS的配置与工具实践

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

Flipper Zero 上的 Doom 移植版:doom-flipper-zero 射线投射引擎原理与 .fap 安装实战

发布时间:2026/9/14 15:29:02
Flipper Zero 上的 Doom 移植版:doom-flipper-zero 射线投射引擎原理与 .fap 安装实战 Flipper Zero 上的 Doom 移植版doom-flipper-zero 射线投射引擎原理与 .fap 安装实战【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/Flipper导读本文基于当前仓库中 kyhwana/doom-flipper-zero-main 的官方说明与完整源码剖析这款面向 Flipper Zero 的 Doom 移植作它不是原版《DOOM》而是从 Arduino Nano 移植项目 doom-nano 二次移植而来的轻量射线投射Raycasting引擎复用 Doom 精灵图Sprites。读完本文你将掌握它如何在 128×64 单色屏上实现伪 3D 场景、它的实体/关卡/渲染架构如何设计、如何将源码编译为外部应用.fap并安装到 Flipper Zero 的 SD 卡上以及各核心常量的调参含义。项目背景传统意义上的 Will it run Doom?Will it run Doom? 是嵌入式圈子的一个经典梗——开发者热衷于把《DOOM》移植到几乎每一种电子设备上。本项目正是这一传统在 Flipper Zero 上的实践README 中明确说明这不是真正的《DOOM》游戏本体而是基于另一个 Arduino Nano 移植项目 doom-nano 改写而成的移植版。从源码结构看整个移植的核心是一个射线投射渲染引擎Raycasting Engine代码在 doom.c 的renderMap函数注释明确标注 The map raycaster. Based on https://lodev.org/cgtutor/raycasting.html配合 Doom 风格的精灵图资源。作者在 README 中也坦诚地注明This version is very basic and might be improved over time.——即当前版本非常基础可能随时间持续改进。硬件与性能约束下的设计取舍Flipper Zero 是一台资源极其有限的嵌入式设备屏幕仅 128×64 像素单色 LCDCPU 与内存都非常紧张。为了在如此苛刻的环境下跑出流畅的伪 3D 画面项目在 constants.h 中做了大量针对性优化理解这些常量是看懂整个引擎的关键常量值作用说明FRAME_TIME66.666666每帧目标时间毫秒约 15 FPSRES_DIVIDER2水平方向渲染分辨率分频越大越省 CPU、画面越糙Z_RES_DIVIDER2Z-Buffer 分辨率分频以牺牲分辨率换取内存DISTANCE_MULTIPLIER20距离缩放系数将浮点距离转为uint8_t存储以省内存MAX_RENDER_DEPTH12光线最大投射深度墙体的最大可见距离MAX_SPRITE_DISTANCE/MAX_SPRITE_DEPTH8精灵实体最大渲染深度SCREEN_WIDTH/SCREEN_HEIGHT128 / 64屏幕尺寸RENDER_HEIGHT56射线渲染区高度屏幕底部 8 像素留给 HUDMAX_ENTITIES10同时活跃的实体数量上限MAX_STATIC_ENTITIES28休眠/静态实体数量上限MAX_ENTITY_DISTANCE200实体超过此距离即进入休眠doze并移除MAX_ENEMY_VIEW80敌人的索敌/攻击视野距离ENEMY_SPEED/FIREBALL_SPEED0.02 / 0.2敌人移动与火球飞行速度ENEMY_MELEE_DAMAGE/ENEMY_FIREBALL_DAMAGE8 / 20敌人近战/火球对玩家的伤害GUN_MAX_DAMAGE20玩家枪械单发最大伤害ROT_SPEED/MOV_SPEED0.12 / 0.2玩家转身与移动速度GUN_TARGET_POS18枪械复位位置屏幕上的 Y 坐标目标值LEVEL_WIDTH641 6关卡宽度LEVEL_HEIGHT57关卡高度LEVEL_SIZE64/2 × 57关卡数据数组长度几个特别值得注意的工程设计Z-Buffer 用uint8_t存储DISTANCE_MULTIPLIER的注释解释了这一取舍——将距离乘以 20 后再存入无符号 8 位整数既能保留精度又能控制内存占用同时约束MAX_RENDER_DEPTH × DISTANCE_MULTIPLIER不得超过 256。地图数据用 4 位半字节编码一个格子见 types.h 中的图例与 level.h 中的注释每个块仅用 4 bit 存储内存占用减半。FPS 帧率控制与 delta 时间fps()display.h通过忙等待限制到约 15 FPS并计算delta因子让低速帧率下移动仍然一致不过在updateEntities中作者也留下了 TODO 注释坦言应使用 delta 但需要 double 类型和更多内存。如何安装到 Flipper Zero原版 README 给出了安装指引像构建任何其他外部应用.fap一样构建不再需要修改固件。这与仓库目录Applications/Official/source-OLDER/的归档位置一致——该移植版按 Flipper 官方外部应用FAPFlipper Application Package的方式组织。安装的核心流程是准备 Flipper Zero 官方固件开发环境即 flipperzero-firmware 及其 fbtFlipper Build Tool工具链将本项目的源码放入固件仓库的应用目录applications_user/等用户应用目录使用 fbt 编译产出.fap文件例如执行./fbt fap_dist或针对单应用构建把生成的.fap拷贝到 Flipper Zero SD 卡的apps/Games/目录具体分类见下方应用清单的fap_category从 Flipper Zero 的应用菜单Applications中找到并启动。项目根目录的 application.fam 是 fbt 的 FAP 应用清单它把上述元信息全部声明好App( appidDOOM, nameDOOM, apptypeFlipperAppType.EXTERNAL, entry_pointdoom_app, cdefines[APP_DOOM_GAME], requires[ gui, music_player, ], stack_size4 * 1024, order75, fap_icondoom_10px.png, fap_categoryGames, )各字段含义与要点appidDOOM应用唯一标识fbt 用它来索引与依赖解析apptypeFlipperAppType.EXTERNAL外部应用类型即编译为独立.fap文件从 SD 卡加载无需修改固件README 强调的 No firmware modification needed anymore!entry_pointdoom_app应用入口函数对应 doom.c 中的int32_t doom_app()requires[gui, music_player]声明依赖系统 GUI 服务与音乐播放器服务用于播放 Doom 主题曲stack_size4 * 1024应用栈大小为 4 KB对嵌入式小内存环境是重要约束fap_icondoom_10px.png应用菜单显示的 10×10 图标位于仓库根目录fap_categoryGames安装后在应用菜单归入 Games游戏分类。应用生命周期与主循环架构doom_app()doom.c是标准的 Flipper 外部应用骨架展示了 Flipper SDK 下 GUI 应用的标准写法创建事件队列与状态furi_message_queue_alloc(8, sizeof(PluginEvent))分配可容纳 8 个事件的队列PluginState结构体承载玩家、实体数组、场景、按键状态、通知服务等全部运行状态。互斥锁保护状态init_mutex创建ValueMutex渲染回调与输入回调通过acquire_mutex/release_mutex访问共享状态避免并发冲突。定时器驱动游戏循环furi_timer_alloc(doom_game_update_timer_callback, FuriTimerTypePeriodic, ...)创建周期定时器以furi_kernel_get_tick_frequency() / 12约 12 Hz的频率向队列投递EventTypeTick事件驱动doom_game_tick()推进游戏逻辑。ViewPort 与 GUI 注册view_port_draw_callback_set绑定渲染回调render_callbackview_port_input_callback_set绑定输入回调input_callback最后gui_add_view_port(gui, view_port, GuiLayerFullscreen)以全屏层注册到 GUI 服务。输入处理InputKeyBack退出应用InputKeyOk在 Intro 界面开始游戏、游戏中开火、死亡后返回 IntroInputKeyUp/Down/Left/Right控制移动与转向按下/释放分别置位/清除标志位。资源清理退出时依次释放定时器、ViewPort、GUI 引用、消息队列与状态内存。渲染回调render_callback按scene分派INTRO场景直接canvas_draw_icon绘制 Logo对应仓库assets/logo_inv.png编译产物GAME_PLAY场景按顺序执行updateEntities更新实体与 AI→renderGun绘制武器→renderMap射线投射画墙体→renderEntities绘制精灵→renderHud/updateHud/renderStatsHUD 与调试信息。游戏场景与操作手感两个场景INTRO值为 0标题画面显示 Doom 风格 Logoassets/logo_inv.png按 OK 键进入游戏。GAME_PLAY值为 1正式游戏场景。玩家操作映射按键与功能的对应关系从 doom.c 的输入回调中可以完整还原按键功能上键Up前进加速到MOV_SPEED带 0.4 的插值平滑下键Down后退左键Left向左转身旋转方向向量dir与相机平面plane右键Right向右转身OK 键OkIntro 界面开始游戏游戏中开火玩家死亡后返回 Intro返回键Back退出应用移动与转身有平滑感设计前进/后退通过速度插值velocity (MOV_SPEED - velocity) * 0.4实现加速松开后速度按 0.5 系数衰减转身使用二维旋转矩阵同时更新dir与plane向量view_height随正弦波抖动模拟跑步时的镜头起伏JOGGING_SPEED控制抖动频率枪械也随脚步摆动——这就是jogging奔跑抖动效果。射线投射渲染如何在 128×64 屏上画出伪 3DrenderMap()doom.c是整个 3D 效果的核心算法基于经典的 LodeV 教程逐列扫描按RES_DIVIDER步长遍历屏幕每一列计算相机空间射线方向ray dir plane * camera_x其中camera_x 2*x/SCREEN_WIDTH - 1将像素列映射到 [-1, 1]。DDA 步进计算射线在 X/Y 方向上的delta以side_x side_y判断下一步走哪个方向逐格穿越地图直到命中E_WALL或达到MAX_RENDER_DEPTH。垂直投影命中墙体后计算垂直距离画线高度line_height RENDER_HEIGHT / distance配合按距离分级的渐变GRADIENT_COUNT与side墙的南北/东西面做明暗区分产生立体感。Z-Buffer将每列距离存入zbuffer[x / Z_RES_DIVIDER]供后续精灵渲染做遮挡判断。精灵渲染renderEntities()translateIntoView()doom.c完成从世界坐标到屏幕坐标的相机空间变换矩阵求逆按距离从远到近排序梳排序sortEntities逐精灵与 Z-Buffer 比较后缩放绘制。drawSpritedisplay.h实现了带透明遮罩mask、按距离缩放、支持精灵帧索引与 Z 轴遮挡的自定义位图绘制。实体系统与敌人 AI实体类型定义在 types.h状态机定义在 entities.h实体类型E_FLOOR(0x0)、E_WALL(0xF)、E_PLAYER(0x1)、E_ENEMY(0x2)、E_DOOR(0x4)、E_LOCKEDDOOR(0x5)、E_EXIT(0x7)以及可拾取物≥0x8E_MEDIKIT(0x8)、E_KEY(0x9)E_FIREBALL(0xA) 仅存在于运行期不在地图上。状态机S_STAND(0)、S_ALERT(1)、S_FIRING(2)、S_MELEE(3)、S_HIT(4)、S_DEAD(5)、S_HIDDEN(6)、S_OPEN(7)、S_CLOSE(8)。UID 标识create_uid(type, x, y)用类型坐标生成 16 位唯一 IDuid_get_type取出类型实体管理与碰撞检测都基于 UID。敌人ImpAI 在 doom.c 的updateEntities中实现逻辑清晰警戒ALERT玩家在ENEMY_MELEE_DIST(6) 与MAX_ENEMY_VIEW(80) 之间时敌人进入警戒并逐步逼近玩家每 20 帧抛出一枚火球spawnFireball角度按 45 份/PI 离散化随后进入S_FIRING状态。近战MELEE距离小于 6 时转为近战蓄力 10 帧后对玩家造成 8 点伤害并闪烁屏幕。受击HIT被打中后进入受击状态 4 帧然后回到警戒。死亡DEAD血量归零进入死亡状态播放 6 帧死亡动画后移除。距离休眠Doze超过MAX_ENTITY_DISTANCE(200) 的实体直接从活动数组移除渲染时通过射线按需重新生成spawnEntity这是典型的按需加载内存优化。玩家与实体的碰撞检测detectCollision分别对 X/Y 轴独立判定墙体直接返回 UID 阻挡移动敌人非死亡/隐藏状态在ENEMY_COLLIDER_DIST(4) 内且不断靠近时触发碰撞。道具效果医疗包E_MEDIKIT距离小于ITEM_COLLIDER_DIST(6) 时拾取生命值fmin(100, health50)触发长音通知。钥匙E_KEY拾取后player.keys同样触发长音。火球命中玩家造成 20 点伤害并闪屏玩家生命归零时视角下沉、枪械落下按 OK 返回标题。音乐与音效用 RTTTL 播放 Doom 主题曲项目通过requires[music_player]依赖系统音乐播放器服务使用自定义的doom_music_player_workerdoom_music_player_worker.h作为播放后端支持从文件/字符串加载 RTTTL 格式曲目、设置音量与回调。sound.h 内嵌了 Doom 主题曲的 RTTTL 数据dsintro并在应用启动时通过music_player_worker_load_rtttl_from_stringmusic_player_worker_start播放进入游戏后停止主题曲。开枪等短促效果则通过 Flipper 的 Notification 服务播放sequence_short_sound/sequence_long_sound对应 C5/C3 短音与长音序列见 doom.c。音量分级常量MUSIC_PLAYER_VOLUMES[] {0, .25, .5, .75, 1}当前实现默认音量取第 2 档0.5。关卡数据Wolfenstein 3D E1M1 的 ASCII 地图level.h 中注释明确说明关卡布局基于 Wolfenstein 3D 的第一关 E1M1并保留了完整的 ASCII 地图蓝图########....####... #.K.######D#######... #.E....D...E...###... ...地图图例与types.h对应#墙、.地板、P玩家出生点、E敌人、D门、L锁门、K钥匙、M医疗包、X出口。存储上作者用正则替换把 ASCII 地图压缩成 4-bit 每格的const uint8_t sto_level_1[LEVEL_SIZE]数组LEVEL_SIZE 64/2 × 57 1824字节并通过getBlockAt()doom.c按半字节位运算还原方块类型——y 坐标按逆序读取(LEVEL_HEIGHT-1-y) * LEVEL_WIDTH x) / 2定位字节、x % 2决定取高/低 4 位。initializeLevel()扫描地图找到E_PLAYER方块后创建玩家对象坐标取格子中心 0.5。源码目录速览文件职责doom.c应用入口、主循环、射线渲染、实体 AI、碰撞、输入constants.h全部调参常量性能、速度、伤害、屏幕尺寸types.h实体类型、UID、坐标与基础工具entities.h玩家/实体/静态实体结构与工厂宏level.h关卡 ASCII 蓝图与压缩后的地图数据display.h全部绘制原语点/线/精灵/位图/文字/FPS 控制sound.hRTTTL 音乐数据与 MusicPlayer 模型doom_music_player_worker.c/.h音乐播放工作线程封装application.famfbt 应用清单构建元数据compiled/assets_icons.c/.h由 assets 位图编译生成的图标/精灵数组assets/原始位图资源与运行截图总结与扩展方向doom-flipper-zero 是一个麻雀虽小五脏俱全的嵌入式移植范本它在约 4 KB 栈空间的限制下完整实现了射线投射 3D 渲染、Z-Buffer 遮挡、按需实体生成、敌人状态机 AI、碰撞检测、武器/HUD 与 RTTTL 音乐播放并且以标准 FAP 外部应用形式分发无需修改固件即可安装运行。源码中多处 TODO 注释也指明了可行的改进方向例如使用 delta 时间驱动、实现门/出口/静态实体交互等——对想要研究嵌入式游戏引擎或 Flipper Zero 应用开发的读者来说是一份值得通读的参考实现。【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/Flipper创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号