
Flipper Zero 上的 DnD Dice桌面角色扮演骰子应用与 FAP 源码全解析【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/FlipperDnD Dice是一款运行在Flipper Zero上的骰子投掷应用专为龙与地下城DD等桌面角色扮演游戏的投骰场景设计。本文将以 DnD Dice 官方 README 为骨架结合其完整源码dice_app.c、constants.h、application.fam带你掌握这款应用的操作方式、界面设计、底层状态机与动画实现并手把手完成从源码到.fap安装包的编译与部署。一、应用简介一枚随身携带的虚拟骰袋实体骰子容易丢失、滚动不可控在旅途中开团时尤其不便。DnD Dice 把桌面角色扮演中最常用的骰子全部装进 Flipper Zero只需按几下按键就能完成投掷并自动累加结果。根据 README 与源码中的dice_types[]表constants.h应用共内置8 种骰型骰型面数type说明Coin2硬币正反用于判定类场景d44四面体骰d66六面骰最常见的标准骰d88八面体骰d1010十面骰d1212十二面体骰d2020二十面骰DD 的核心检定骰d100100百面骰常以两个 d10 模拟每种骰型在源码中都携带type面数、坐标x/y与显示名称name界面上的所有骰子图标都由assets/目录下的像素图提供如assets/d4_1.png、assets/d20_4.png等均为 35×35 的 XBM 资源并配套保留了sources/目录下的.pixil源文件供二次绘制。二、界面与操作指南应用采用全屏 GUIGuiLayerFullscreen与像素风界面主界面布局如下主界面从上到下依次是当前骰型图标与名称、左右切换箭头、骰子数量设置、底部 EXIT / OK ROLL 按钮。完整按键操作逻辑对应 dice_app.c 中的按键分发左 / 右方向键在 8 种骰型之间切换。切换时会触发SwipeLeftState/SwipeRightState滑动动画代码以SWIPE_DIST 11像素步进、DICE_GAP 44像素间距让骰子图标整体平移见 constants.h。上 / 下方向键调整单次投掷的骰子数量范围1 ~ 10上限由MAX_DICE_COUNT 10定义。特别地isOneDice()会锁定Coin 与 d100两种骰型的数量恒为 1constants.h因为这两者本身就是单枚语义。OK 键中心键触发投掷进入动画播放与结果展示。BACK 键在结果界面按下返回骰子选择在选择界面按下则退出应用。投掷完成后的结果界面如下结果界面用大字号显示点数和并在其下方以次级字体列出每一枚骰子的单独结果如4,4,1,3,2,6多枚投掷时清晰可读符合跑团记录习惯。三、源码结构一览整个应用只有四个源码/配置文件结构非常精简非常适合作为 Flipper Zero 应用开发的入门范本文件职责dice_app.c应用入口、事件循环、状态更新、UI 绘制constants.h常量、骰型表、动画帧表、状态机定义与工具函数application.famFAP 应用清单构建元数据LICENSE.mdGPL v3 开源许可证其中application.fam是 Flipper 构建工具 fbt 识别应用的清单文件内容如下App( appidDND_Dice_app, nameDnD Dice [Ka3u6y6a], apptypeFlipperAppType.EXTERNAL, entry_pointdice_dnd_app, cdefines[APP_DICE], requires[gui], stack_size1 * 1024, order90, fap_iconicon.png, fap_categoryGames, fap_icon_assetsassets, )各字段含义appid / name应用唯一标识与显示名apptype EXTERNAL编译为独立.fap插件而非烧入固件entry_point入口函数名dice_dnd_app对应源码中的int32_t dice_dnd_app(void* p)dice_app.crequires [gui]声明依赖 GUI 子系统stack_size任务栈 1KBfap_category Games决定安装到 SD 卡后出现在apps/Games分类下README 的安装路径正是该目录fap_icon / fap_icon_assets应用图标与图标资源目录。四、核心实现深度解析4.1 六状态状态机应用的全部逻辑建立在一个简洁的状态机上枚举定义在 constants.hSelectState → SwipeLeftState / SwipeRightState骰型滑动切换 → AnimState投掷动画→ AnimResultState结果滑入动画→ ResultState结果展示每个定时器 tick见下文 4.4都会驱动update()dice_app.c推进状态滑动状态逐帧平移骰子直到归位AnimState播放骰子旋转帧AnimResultState让结果边框沿result_frame_pos_y[] {-30, -20, -10, 0}逐帧下落落到0时进入最终ResultState。4.2 随机数与点数计算投掷核心逻辑在roll()dice_app.cstate-rolled_dices[i] (rand() % dice_types[state-dice_index].type) 1; state-roll_result state-rolled_dices[i];每一枚骰子的点数通过rand() % 面数 1生成d4 得到 1~4d20 得到 1~20Coin 得到 1~2单枚结果存入rolled_dices[MAX_DICE_COUNT]数组同时累加到roll_result作为点数总和。结果界面即同时展示总和与逐枚明细。4.3 双套动画帧系统动画分为硬币与骰子两套constants.h硬币MAX_COIN_FRAMES 9帧。正/反面结果由coin_set_start()/coin_set_end()在投掷前动态改写首尾帧——正面结果为正-正头尾、反面为反-反头尾从而让动画结束时正确落定在结果面上骰子每种骰型MAX_DICE_FRAMES 4帧旋转动画按(骰型序号 - 1) * 4 帧号索引到dice_frames[]表中d4/d6/d8/d10/d12/d20/d100 共 28 帧。所有帧都是assets/下的 35×35 像素图标I_d4_1、I_d6_3……由 fbt 构建时自动从fap_icon_assetsassets生成头文件引用。4.4 事件驱动架构与渲染应用遵循 Flipper Zero 标准的事件驱动范式dice_app.c分配FuriMessageQueue事件队列容量 8事件类型分为EventTypeTick定时器与EventTypeKey按键创建ValueMutex保护共享的State避免绘制与逻辑线程竞争注册ViewPort的绘制回调draw_callback与输入回调input_callback并以furi_timer_alloc(FuriTimerTypePeriodic, ...)建立0.2 秒周期的动画 tickfuri_kernel_get_tick_frequency() * 0.2主循环furi_message_queue_get()阻塞取事件超时 100ms按键事件里按InputTypePress处理方向键、OK 与 BACK每次循环末尾调用view_port_update()触发重绘退出时按序释放定时器、队列、ViewPort 并furi_record_close(RECORD_GUI)。绘制层将 UI 拆成draw_ui骰名、箭头、数量、按钮、draw_dice骰子图标与draw_results结果框与文字三个函数按状态机决定绘制哪部分——例如ResultState下不再绘制骰子而绘制结果。五、编译与部署从源码到 FAP 插件README 给出的完整编译流程如下以官方固件为例其他固件同理准备固件源码克隆 flipperzero-firmwareFlipperDevices 官方仓库或你所使用的第三方固件例如 Unleashed 系固件源码建立符号链接在固件仓库的applications_user目录下创建一个名为dice的符号链接指向本应用的源码目录即Applications/Official/source-OLDER/grnch/dice2/例如执行ln -s /path/to/dice2 dice执行编译在固件仓库根目录运行./fbt fap_dice_dnd_appfbt 会根据application.fam中的appidDND_Dice_app与entry_pointdice_dnd_app自动定位入口函数并产出插件安装到设备将产物build/f7-firmware-D/.extapps/dice_dnd_app.fap复制到 SD 卡的apps/Games目录与application.fam的fap_categoryGames对应或通过qFlipper桌面工具安装到设备。安装后进入 Flipper Zero 的Applications应用菜单即可找到该游戏。需要说明两点适用前提FAP 与固件的 API 版本强绑定。按照本仓库 Applications/ReadMe.md 的说明RogueMaster 与 Unleashed 固件之间的 FAP 文件可以互换但由于 API 差异它们与官方固件之间不通用——这也是 README 要求为你的固件分别编译的根本原因如果不想搭建完整固件环境也可以使用uFBTmicro Flipper Build ToolFlipperDevices 提供的轻量构建工具直接编译独立的 FAP这是仓库 README 中推荐的另一种构建路径。六、在仓库中的版本脉络本目录位于 Applications/Official/source-OLDER 下的grnch/dice2/对应作者 grnch 维护的官方固件兼容版本。仓库中还保留了相关演化痕迹可供对照学习grnch/dice/同一作者的早期单文件版本dice.ckyhwana/dice2/与grnch/dice2同源的镜像版本kyhwana/dice2/README.mdxMasterX/下的dice/、rmdice/与flipperzero-yatzee-main/同主题的骰子/游戏变体实现。对比阅读这些版本可以直观看到从单文件到constants.h抽离常量、从简单投掷到完整动画状态机的演进思路。七、开源许可本应用以GNU General Public License v3.0GPL v3授权发布完整许可文本见 LICENSE.md。这意味着你可以自由使用、修改与再分发但衍生作品需以相同许可证开源。结语DnD Dice 虽是一个体量极小的 Flipper Zero 应用却完整覆盖了骰型配置 → 数量设置 → 随机投掷 → 动画反馈 → 结果展示的闭环其六状态状态机、双套动画帧表与事件驱动 GUI 范式是学习 Flipper Zero FAP 开发的高质量范例。无论你是想用它替代实体骰子还是想以此为模板写出自己的第一个像素风应用都可以从本仓库的这份源码直接上手。【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/Flipper创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考