[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article:60-eaf24d39":3},{"article":4,"revisions":15},{"id":5,"author_id":6,"firmware_project_id":7,"slug":8,"published_revision_id":9,"visibility":10,"moderation_lock_reason":11,"version":12,"created_at":13,"updated_at":14},"ed967abe-0a6d-48d7-be82-f40382837b1c","5e0f2aa3-425b-4b7c-82a7-f9f923204a49","eaf24d39-7715-46b4-abec-cd05d02094f3","60-eaf24d39","ebe27cbe-09ee-4a78-b318-6afab9168ffd","public",null,17,"2026-10-02T12:32:15.509Z","2026-10-02T15:52:33.319Z",[16],{"id":9,"article_id":5,"revision_no":17,"state":18,"source_revision_id":19,"change_summary":20,"version":21,"submitted_at":22,"reviewed_at":23,"published_at":24,"created_at":25,"description":26,"rendered_description":27,"content":28},3,"published","e61e524b-a06b-44b3-b891-83a5a9965ee3","",6,"2026-10-02T12:56:31.241Z","2026-10-02T12:58:31.063Z","2026-10-02T12:58:31.095Z","2026-10-02T12:49:37.277Z","# 60's Striker —— 是男人就坚持 60 秒\n \n基于 **ESP-Mosaico**（ESP32-S31 + 480×480 显示屏 + 交互子板）复刻的经典弹幕生存游戏：一条命、不能射击、只用左右移动，在越来越疯狂的字弹地狱里**坚持 60 秒**。\n\n \n## 玩法\n \n- **一条命、不能射击**——你唯一的武器是走位。左右移动，躲开一切。\n- 顶部巨大的生存计时器实时跳动：`23.4`、`41.7`……看着它活过 60 秒。\n- 撑过 **60.00 秒** → `CONGRATULATIONS · YOU ARE A MAN!`（你是男人！）；\n  中弹死亡 → 结算本局生存时间，按键**秒开下一局**。\n- **生存时间排行榜 Top 5**（0.1 秒精度），保存在设备 NVS 中，重启不丢。\n\n \n## 难度设计（经典曲线）\n \n复刻原版 Flash 游戏的成瘾性节奏——**前几秒几乎空场，之后逐级解锁**：\n \n| 时间 | 解锁内容 |\n| --- | --- |\n| 0–3 s | 宽限期：场上几乎无弹，热身走位 |\n| 3 s | 第一个敌机进场（且 2 秒后才开第一枪） |\n| 5 s | 顶部弹雨开始（间隔从 3 s 逐渐压到 0.4 s） |\n| 全程 | 瞄准弹 \u002F 三向散射 \u002F 环形弹，密度与速度随时间线性爬升至 **2 倍** |\n| 32 s | 带缺口的弹墙（惩罚站桩） |\n| 45–60 s | 全类型齐发，最终狂潮 |\n \n## 操作\n \n| 输入 | 动作 |\n| --- | --- |\n| 交互子板 **左 \u002F 右实体键** | 左右移动（按住持续移动，松开即停） |\n| 屏幕左下 \u002F 右下角触摸（隐形区域） | 同上，无子板时的后备 |\n| 任意键 \u002F 触屏（标题或结算画面） | 开始 \u002F 重开一局 |\n| Host 模拟器 | `A` \u002F `D` 移动，`W` \u002F `S` 纵向（调试用），`P` 暂停 |\n \n**屏幕重力旋转**：交互子板插在右侧时画面自动旋转 90°——子板永远位于画面下方，握持方向即操作方向。\n \n## 技术亮点\n \n- **弹幕引擎**：480×480 RGB565 画布上 30 fps 软件渲染，零图片资源——全部图形由矢量图元与自绘 5×7 像素字体构成（字体支持 90° 旋转渲染），固件仅 1.3 MB。\n- **交互子板按键驱动修复**：按键焊盘与触摸电极共用且**没有内部上拉**（实测主动充 3.3 V 后仍读低），普通 GPIO 读取会在按压后锁死数分钟。补丁实现了**充电式读取**——每个采样周期先把焊盘充到高电平再采样，配合非对称去抖（按下 2 次确认 \u002F 松开 1 次立即）与航向保持（两键冲突时保持当前方向，抑制相邻焊盘互容耦合的幻影信号），做到\"按下即动、松开即停\"。\n- **CST9220 触摸驱动自愈**：针对 LCD 触摸控制器每秒自校准产生的无效帧突发与偶发楔死，本地化补丁只在连续 300 帧异常后重建触摸模式序列。\n- **可移植架构**：游戏模型是纯 C（Host 模拟器与设备共用同一份代码），输入\u002F渲染分层适配；Host 网页模拟器支持录制回放与脚本化测试（本次开发中完成了 8 步输入矩阵的自动化验证）。\n- **排行榜持久化**：NVS blob 存储，游戏通过保存回调解耦存储实现。\n \n## 硬件与构建\n \n**硬件**：ESP-Mosaico 主机（ESP32-S31，CO5300 480×480 QSPI 屏）+ 交互子板（右槽）。\n \n**构建**（需要 ESP-IDF `7b9cc1ac…` 与 workspace 布局，见 [docs](docs\u002F)）：\n \n```sh\ngit clone https:\u002F\u002Fgithub.com\u002Fzaxchou\u002Fesp-mosaico-striker.git\ncd esp-mosaico-striker\ngit submodule update --init submodule\u002Fesp-mosaico-utils submodule\u002Fraylib-lite-engine\ngit apply patches\u002F0001-bsp-interact-charged-key-read.patch   # 交互子板按键驱动修复\npython mosaico.py game sim  --project projects\u002Fstriker1945   # Host 网页模拟器\npython mosaico.py game build --project projects\u002Fstriker1945  # 设备固件\npython mosaico.py iris system-update --project projects\u002Fstriker1945  # 安装到设备\n```\n \n**固件**：`firmware\u002Fstriker1945.bin`（应用分区镜像，esp32s31）。完整安装（含保留 Recovery 契约）请使用上面的 `iris system-update` 命令。\n \n## 目录结构\n \n```\nprojects\u002Fstriker1945\u002F     游戏源码（main\u002F 游戏模型+渲染+输入适配, components\u002F 本地驱动补丁）\npatches\u002F                  BSP 交互子板按键驱动补丁（git apply 方式提供）\nfirmware\u002F                 比赛固件 bin\nprojects\u002Fstriker1945\u002Fscreenshots\u002F   游戏截图\nsubmodule\u002F                上游 BSP \u002F 引擎 \u002F 工具链（pinned gitlinks）\n```\n \n## 已知限制\n \n- 触摸外设路径读取按键在实测中不可用（焊盘无上拉导致基准漂移），最终方案为 GPIO 充电读取；LCD 触摸控制器的自校准警告（约每秒一次）为正常现象，不影响触摸操作。\n- 屏幕左下\u002F右下的隐形触摸区与实体按键功能相同，保留作为无子板时的后备。\n \n---\n \n*ARE YOU A MAN?*","\u003Ch1>60's Striker —— 是男人就坚持 60 秒\u003C\u002Fh1>\n\u003Cp>基于 \u003Cstrong>ESP-Mosaico\u003C\u002Fstrong>（ESP32-S31 + 480×480 显示屏 + 交互子板）复刻的经典弹幕生存游戏：一条命、不能射击、只用左右移动，在越来越疯狂的字弹地狱里\u003Cstrong>坚持 60 秒\u003C\u002Fstrong>。\u003C\u002Fp>\n\u003Ch2>玩法\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Cstrong>一条命、不能射击\u003C\u002Fstrong>——你唯一的武器是走位。左右移动，躲开一切。\u003C\u002Fli>\n\u003Cli>顶部巨大的生存计时器实时跳动：\u003Ccode>23.4\u003C\u002Fcode>、\u003Ccode>41.7\u003C\u002Fcode>……看着它活过 60 秒。\u003C\u002Fli>\n\u003Cli>撑过 \u003Cstrong>60.00 秒\u003C\u002Fstrong> → \u003Ccode>CONGRATULATIONS · YOU ARE A MAN!\u003C\u002Fcode>（你是男人！）；\n中弹死亡 → 结算本局生存时间，按键\u003Cstrong>秒开下一局\u003C\u002Fstrong>。\u003C\u002Fli>\n\u003Cli>\u003Cstrong>生存时间排行榜 Top 5\u003C\u002Fstrong>（0.1 秒精度），保存在设备 NVS 中，重启不丢。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>难度设计（经典曲线）\u003C\u002Fh2>\n\u003Cp>复刻原版 Flash 游戏的成瘾性节奏——\u003Cstrong>前几秒几乎空场，之后逐级解锁\u003C\u002Fstrong>：\u003C\u002Fp>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>时间\u003C\u002Fth>\n\u003Cth>解锁内容\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\u003Ctr>\n\u003Ctd>0–3 s\u003C\u002Ftd>\n\u003Ctd>宽限期：场上几乎无弹，热身走位\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>3 s\u003C\u002Ftd>\n\u003Ctd>第一个敌机进场（且 2 秒后才开第一枪）\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>5 s\u003C\u002Ftd>\n\u003Ctd>顶部弹雨开始（间隔从 3 s 逐渐压到 0.4 s）\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>全程\u003C\u002Ftd>\n\u003Ctd>瞄准弹 \u002F 三向散射 \u002F 环形弹，密度与速度随时间线性爬升至 \u003Cstrong>2 倍\u003C\u002Fstrong>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>32 s\u003C\u002Ftd>\n\u003Ctd>带缺口的弹墙（惩罚站桩）\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>45–60 s\u003C\u002Ftd>\n\u003Ctd>全类型齐发，最终狂潮\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Ch2>操作\u003C\u002Fh2>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>输入\u003C\u002Fth>\n\u003Cth>动作\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\u003Ctr>\n\u003Ctd>交互子板 \u003Cstrong>左 \u002F 右实体键\u003C\u002Fstrong>\u003C\u002Ftd>\n\u003Ctd>左右移动（按住持续移动，松开即停）\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>屏幕左下 \u002F 右下角触摸（隐形区域）\u003C\u002Ftd>\n\u003Ctd>同上，无子板时的后备\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>任意键 \u002F 触屏（标题或结算画面）\u003C\u002Ftd>\n\u003Ctd>开始 \u002F 重开一局\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Host 模拟器\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>A\u003C\u002Fcode> \u002F \u003Ccode>D\u003C\u002Fcode> 移动，\u003Ccode>W\u003C\u002Fcode> \u002F \u003Ccode>S\u003C\u002Fcode> 纵向（调试用），\u003Ccode>P\u003C\u002Fcode> 暂停\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Cp>\u003Cstrong>屏幕重力旋转\u003C\u002Fstrong>：交互子板插在右侧时画面自动旋转 90°——子板永远位于画面下方，握持方向即操作方向。\u003C\u002Fp>\n\u003Ch2>技术亮点\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Cstrong>弹幕引擎\u003C\u002Fstrong>：480×480 RGB565 画布上 30 fps 软件渲染，零图片资源——全部图形由矢量图元与自绘 5×7 像素字体构成（字体支持 90° 旋转渲染），固件仅 1.3 MB。\u003C\u002Fli>\n\u003Cli>\u003Cstrong>交互子板按键驱动修复\u003C\u002Fstrong>：按键焊盘与触摸电极共用且\u003Cstrong>没有内部上拉\u003C\u002Fstrong>（实测主动充 3.3 V 后仍读低），普通 GPIO 读取会在按压后锁死数分钟。补丁实现了\u003Cstrong>充电式读取\u003C\u002Fstrong>——每个采样周期先把焊盘充到高电平再采样，配合非对称去抖（按下 2 次确认 \u002F 松开 1 次立即）与航向保持（两键冲突时保持当前方向，抑制相邻焊盘互容耦合的幻影信号），做到\"按下即动、松开即停\"。\u003C\u002Fli>\n\u003Cli>\u003Cstrong>CST9220 触摸驱动自愈\u003C\u002Fstrong>：针对 LCD 触摸控制器每秒自校准产生的无效帧突发与偶发楔死，本地化补丁只在连续 300 帧异常后重建触摸模式序列。\u003C\u002Fli>\n\u003Cli>\u003Cstrong>可移植架构\u003C\u002Fstrong>：游戏模型是纯 C（Host 模拟器与设备共用同一份代码），输入\u002F渲染分层适配；Host 网页模拟器支持录制回放与脚本化测试（本次开发中完成了 8 步输入矩阵的自动化验证）。\u003C\u002Fli>\n\u003Cli>\u003Cstrong>排行榜持久化\u003C\u002Fstrong>：NVS blob 存储，游戏通过保存回调解耦存储实现。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>硬件与构建\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>硬件\u003C\u002Fstrong>：ESP-Mosaico 主机（ESP32-S31，CO5300 480×480 QSPI 屏）+ 交互子板（右槽）。\u003C\u002Fp>\n\u003Cp>\u003Cstrong>构建\u003C\u002Fstrong>（需要 ESP-IDF \u003Ccode>7b9cc1ac…\u003C\u002Fcode> 与 workspace 布局，见 \u003Ca href=\"docs\u002F\" rel=\"nofollow noopener noreferrer\">docs\u003C\u002Fa>）：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>git clone https:\u002F\u002Fgithub.com\u002Fzaxchou\u002Fesp-mosaico-striker.git\ncd esp-mosaico-striker\ngit submodule update --init submodule\u002Fesp-mosaico-utils submodule\u002Fraylib-lite-engine\ngit apply patches\u002F0001-bsp-interact-charged-key-read.patch   # 交互子板按键驱动修复\npython mosaico.py game sim  --project projects\u002Fstriker1945   # Host 网页模拟器\npython mosaico.py game build --project projects\u002Fstriker1945  # 设备固件\npython mosaico.py iris system-update --project projects\u002Fstriker1945  # 安装到设备\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Cstrong>固件\u003C\u002Fstrong>：\u003Ccode>firmware\u002Fstriker1945.bin\u003C\u002Fcode>（应用分区镜像，esp32s31）。完整安装（含保留 Recovery 契约）请使用上面的 \u003Ccode>iris system-update\u003C\u002Fcode> 命令。\u003C\u002Fp>\n\u003Ch2>目录结构\u003C\u002Fh2>\n\u003Cpre>\u003Ccode>projects\u002Fstriker1945\u002F     游戏源码（main\u002F 游戏模型+渲染+输入适配, components\u002F 本地驱动补丁）\npatches\u002F                  BSP 交互子板按键驱动补丁（git apply 方式提供）\nfirmware\u002F                 比赛固件 bin\nprojects\u002Fstriker1945\u002Fscreenshots\u002F   游戏截图\nsubmodule\u002F                上游 BSP \u002F 引擎 \u002F 工具链（pinned gitlinks）\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>已知限制\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>触摸外设路径读取按键在实测中不可用（焊盘无上拉导致基准漂移），最终方案为 GPIO 充电读取；LCD 触摸控制器的自校准警告（约每秒一次）为正常现象，不影响触摸操作。\u003C\u002Fli>\n\u003Cli>屏幕左下\u002F右下的隐形触摸区与实体按键功能相同，保留作为无子板时的后备。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Chr \u002F>\n\u003Cp>\u003Cem>ARE YOU A MAN?\u003C\u002Fem>\u003C\u002Fp>\n",{"title":29,"categories":30,"boards":32,"tags":34,"cover_images":35,"external_links":37,"attachments":42,"current_version":65,"license":66,"firmware_variants":67},"经典系列躲子弹！是男人就坚持 60 秒",[31],"display",[33],"multifunction",[],[36],"\u002Fapi\u002Fv1\u002Ffiles\u002F4b1df03d-05c3-40ba-8971-bcecc50eb82e.webp",[38],{"label":39,"url":40,"platform":41},"Github","https:\u002F\u002Fgithub.com\u002Fzaxchou\u002Fesp-mosaico-striker","github",[43,48,52,56,60],{"id":44,"name":45,"size":46,"media_type":47,"upload_id":44},"9a01ed4c-ea09-4e85-ab5a-c8832289531a.webp","gameover.webp",7954,"image\u002Fwebp",{"id":49,"name":50,"size":51,"media_type":47,"upload_id":49},"01c32ac4-29f8-4d27-81a1-5d24e1de8229.webp","gameplay.webp",3014,{"id":53,"name":54,"size":55,"media_type":47,"upload_id":53},"208d2e98-8abd-4876-83ee-945d2760b455.webp","title.webp",7830,{"id":57,"name":58,"size":59,"media_type":47,"upload_id":57},"2e44e092-c8a6-45f1-b3b8-5a060ad4bc05.webp","win.webp",11996,{"id":61,"name":62,"size":63,"media_type":64,"upload_id":61},"7c4ff687-7a2c-431f-a9ec-4327343c705d.mp4","1000073720.mp4",6387611,"application\u002Foctet-stream","1.0.0","MIT",[68],{"type":69,"partitions":70,"iris":71},"iris",[],{"bundle_asset_id":72},"9a3c0348-e791-4611-b1f0-9cb493bdbfb4.irisfw"]