为什么要拿弹球来测试开发通道
前一阶段,我给 ESP Mini App 做了本地工作台:作者可以查看示例、编辑 Manifest、构建 WASM、在浏览器里预览,再导出投稿包。界面能把按钮摆出来,还不等于陌生开发者真的能完成一次开发。要验证这条通道,我希望选一个足够小、同时又会调用多项平台能力的应用。
重力弹球正合适:板子向某侧倾斜,小球应朝相应方向加速;松手后有惯性和阻尼;撞到边界反弹;触摸可重新放回中心并校准零点。它同时经过传感器输入、定时、绘图和触摸。任何一个环节不一致,都会直接体现在屏幕上。

应用层与平台层怎么分工
Tilt Ball 是独立 WASM 应用。应用负责小球状态、速度、边界判断和画面命令;平台宿主提供受控的时间、显示、触摸与 IMU 能力。这里不需要为每次应用修改重新刷整套设备固件。
text
作者的 C 源码 + manifest.json
│
▼
构建并检查 WASM
│
├── 本地工作台:模拟输入与电脑预览
│
└── ESP-Mosaico:真实 IMU、屏幕和触摸
Manifest 需要把依赖说清楚。这个应用的权限包括 display、touch、sensors;必需外设是屏幕、触摸和 IMU。声明与代码保持一致,平台才能在安装、启动和预览阶段判断缺了什么。它也提醒作者:能在浏览器里填模拟数值,不代表目标板真的具备对应硬件。
核心逻辑:每次定时事件更新一小步
应用入口是 app_init() 与 app_event():前者初始化球的位置和速度,后者接收定时、触摸等事件。一次更新大致分成四步:读取 IMU;以零点为基准计算横纵输入;按时间步更新速度和位置;检查边界并绘制一帧。
c
/* 说明性片段:展示碰撞思路,非完整源码 */
if (ball_x < min_x) {
ball_x = min_x;
if (velocity_x < 0.0f) {
velocity_x = -velocity_x * 0.78f;
}
}
负号使速度反向,0.78 让反弹损失一部分能量。实际代码还对速度做限幅、对加速度做滤波,并限制单次积分时间,避免定时事件延迟后小球一步跨过墙。这个实现并非精密物理引擎;它要检验的是输入、时间和画面能否连续协作。
绘图使用 platform_scene() 提交一组场景命令。画面包括边框、球、阴影和 IMU 读数。把整帧一起交给平台,避免"先清屏、再逐个画"的可见闪烁。读取 IMU 前还检查硬件是否可用;读取失败时显示提示,不把"没有输入"伪装成正常的静止状态。
第一关:电脑预览检查程序是否按预期运行
在本地工作台构建并检查 WASM 后,我打开电脑交互预览。页面提供模拟加速度输入。录屏里修改了 X 轴数值,小球在画布上移动,碰到边界后反弹。这个阶段可以快速确认:
- 应用能加载,画面能稳定绘制。
- 定时事件持续推进物理状态。
- 模拟 IMU 数值能改变运动方向和速度。
- 撞墙后能回弹,触摸能触发校准。
如果这些基础逻辑有问题,立刻回到源码修改并重新构建,成本比反复拔插板子低得多。但预览使用的是人为输入的传感器数值。它不知道板子的真实安装方向,更不能替代拿在手里的操作感。
素材位:可在此插入
通用素材/视频1_电脑预览_发布版.mp4。这段视频记录工作台模拟 IMU;不是实机录像。
第二关:上板后检查"人觉得对不对"
本次验证把 Tilt Ball 构建为已签名 .app ,通过 USB 安装到 ESP-Mosaico。设备屏幕里出现了同一颗球,底部 IMU X/Y 读数随着姿态变化。程序确实在跑,但第一版出现了电脑预览没暴露的问题:左右倾斜时,小球往相反方向移动。

这个现象很容易被误判成"反弹公式写错"。事实上,球的位置会更新、传感器有读数、上下方向也能响应,问题集中在传感器 X 轴与屏幕横向的对应关系。模拟器里填 -2 时我们知道这是一个负数;拿起板子向左倾斜时,用户只关心球是否朝左走。两种检验并不相同。
第一版将横向输入写成 sensor_x - neutral_x。根据 Mosaico 的实际姿态,把它换成 neutral_x - sensor_x,Y 轴映射保持不变:
c
/* 初版 0.1.0 */
raw_x = sensor_x - neutral_x;
/* Mosaico 实测后,0.1.1 */
raw_x = neutral_x - sensor_x;
随后将应用版本升至 0.1.1,重新构建、检查、安装并复测。用户的实机反馈确认:左右与上下移动、碰墙反弹均正常。一个符号的变化很小,却是必须经过实机测试才能放心做出的判断。
素材位:可在此插入
通用素材/视频2_实机测试_发布版.mp4。视频拍的是签名.app的实机运行,不能标成未签名.devapp安装演示。
作者本地测试与正式发布的包要分清
这个平台给作者提供一条更短的实机测试路:在支持开发模式的 Mosaico 固件上,作者可开启开发模式,经 USB 安装本地未签名 .devapp ,自己验证功能。它会显示 [DEV],与正式应用区分。正式在线目录中的应用仍需维护者审核并签名为 .app。
这两个流程解决不同的问题:本地测试回答"我的代码在这块板上能不能用";签名发布回答"这个版本能否进入对所有用户可见的目录"。本次弹球录像属于后者的签名包实机验证,不应该为了让教程显得简单而把两者写成同一次操作。
如果你从作者开发包开始,典型检查顺序是:编辑 Manifest 和源码,在工作台构建并预览;需要上板时下载本地真机测试包,开启板上开发模式,再通过 USB 安装。确认目标板体验后,导出投稿 ZIP,交给维护者做复核、重建、签名与目录发布。
我会保留的验收清单
| 阶段 | 要确认的事 |
|---|---|
| Manifest | 权限、必需外设与代码调用一致 |
| 构建 | WASM 生成,ABI 与包检查通过 |
| 电脑预览 | 画面、模拟输入、碰撞和触摸逻辑可运行 |
| 实机测试 | 方向、手感、反弹、画面稳定性与触摸校准正常 |
| 修正复测 | 代码改动后更新版本,再在目标板上验证 |
| 正式发布 | 人工审核、签名和在线目录属于独立步骤 |

结语
这次最有价值的结果不是一颗球能在屏幕上滚动,而是开发通道经受了一次从作者视角出发的完整试用:电脑预览缩短逻辑调试回路,真实设备指出轴向与手感问题,版本更新后再复测。