使用Rokid AIUI做了一个童年推箱子游戏

一、缘起

家里电视的机顶盒当年带了一堆小游戏,我玩得最久的就是推箱子。一个小人,几个箱子,几个目标点,遥控器方向键一下一下挪。那会儿盒子里的小游戏就那几个,推箱子是唯一一个我能坐那儿玩一整个下午的。后来拿到 Rokid Glasses,翻配置表看到它带陀螺仪(姿态传感器),脑子里的第一个想法就是推箱子。

如果小人的方向不是用手按出来的,而是用头转出来的呢?

推箱子的操作就四个方向,上下左右。脑袋转起来呢,也就是这四个方向。所以做的时候没想什么"老游戏移植"的事,单纯觉得合适,就做了。

更实在的原因是脖子。天天对着屏幕,脖子常年是僵的。戴上眼镜玩两把,左右转头抬头低头,几关下来颈椎就顺带活动开了。就当带游戏皮的颈椎操吧,累了来两关,比干做拉伸好坚持。

语音也加上了。喊「上」「下」「左」「右」小人就走一步,「撤销」「重来」「选择关卡」也都认。脖子不想动的时候就躺着,动动嘴也能玩。


二、AIUI 是什么

AIUI 全称 AI 原生用户界面。名字听着唬人,其实理解起来不复杂:给大模型时代用的 UI 框架,开发者跟 AI 协同搭界面,让 AI 的能力从纯文字变成用户能点、能看、能交互的东西。我第一次接触时就是这么理解的。

一个 AIUI 应用的文件结构是这样的:

bash 复制代码
sokoban/
  AGENTS.md            # 智能体清单:名字、描述、需要的权限
  app.json             # 页面路由
  app.js               # 应用入口
  pages/game/index.ink # 页面(单件组件)
  assets/              # 图片、音频

AGENTS.md 里写的是小助手该怎么被唤起、需要哪些权限。刚看到这文件名的时候我还愣了一下,跟 AGENT 有关但多了一个 S。

markdown 复制代码
## Identity
- **Name**: 推箱子
- **Description**: 运行在 Rokid Glasses 上的头控加语音推箱子游戏......

## Capabilities
- **Permissions**:
  - motion-sensor
  - microphone
  - audio

页面用 .ink 单文件组件,四段结构,写过小程序的人几乎零成本:

html 复制代码
<script def>
{ "navigationBarTitleText": "推箱子" }
</script>

<script setup>
import wx from 'wx';
export default {
  data: { levelNo: '01' },
  onLoad(query) { /* 初始化 */ },
  onKeyUp(event) { /* 镜腿按键 */ },
}
</script>

<page>
  <view class="stage">
    <text class="hud">第 {{ levelNo }} 关</text>
  </view>
</page>

<style>
.stage { display: flex; flex-direction: column; }
</style>

需要注意的是,它的运行时是 Ink(Skia 渲染 + Taffy 布局),不是浏览器。样式和模板支持的是 WXSS/WXML 的一个子集。

这个项目用到了 AIUI 的哪些能力

能力 用在哪
AbsoluteOrientationSensor 读头部姿态四元数,做头控移动
SpeechRecognition 语音说「上/下/左/右」控制小人
Sound 箱子入位、过关、撞墙、死锁的事件音效
wx.setStorageSync 关卡进度、解锁记录、每关最佳步数、方向校准结果
页面级按键事件 onKeyUp 镜腿单击/前滑/后滑,以及拦截系统默认行为
页面生命周期 onShow/onHide 切后台自动暂停传感器和语音
沉浸式页面承载 被唤起后直接全屏,不走对话卡片

三、开发过程

整个项目是用 Claude Code 做的。AIUI 我之前没碰过,所以流程很土:先喂资料让它学,学完再提需求。

第 1 步:先把官方资料喂进去

第一天一行代码没写,全在装官方 skill 和丢资料:

bash 复制代码
npx skills add https://github.com/jsar-project/AIUI/tree/main/skills/aiui-dev

这一步回头看是关键。AIUI 太新,模型那套"通用前端经验"一半是错的,浏览器里合法的样式它写得可自然了,Ink 根本不认。

第 2 步:把想法说清楚

学完之后我只说了一句大白话:

我想做一个能在 Rokid Glasses 上面运行的推箱子游戏,推箱子的小人上下左右行走的方向能根据头部控制上下左右。这个可以做吗?

问完这句我还真有点怕它回一句"做不了"。

它先回了可行性判断和方案,接着把骨架搭了出来:游戏引擎、头控模块、页面、关卡,连测试都有一套。有一点我一开始没注意,后来才发现它把逻辑和 UI 拆开了------引擎全是纯函数,头控也是纯模块,页面只管渲染和接事件。后面改起来顺,就是靠这个分层。

第 3 步:上真机,坑一个个冒出来

代码能跑不代表能用。真正的开发是从第一次戴上眼镜开始的。第一次戴上真机,第一感受是晕:单绿屏就在眼前亮着,转头的时候画面跟着动,还没开始玩游戏,先适应了十来分钟。这之后,我把真机上看到的现象一条条描述给它,它来定位和修。挑几个最有代表性的:

第一个坑:左右能走,抬头低头不灵

传感器给的是四元数,大家一般解成欧拉角 yaw、pitch、roll 来用。左右转头用 yaw,一次就准。抬头低头用 pitch,就时灵时不灵了,把我整不会了。

后来才搞明白,欧拉角分解依赖旋转顺序,有些姿态下 pitch 和 roll 会互相串。眼镜本身又有个固定的俯仰安装角,两件事叠一起,问题被放大了。我当时还以为是阈值的事,越调越乱。

最后干脆绕开角分解,直接从四元数求「参考系竖直轴在设备坐标系里的方向向量」,也就是旋转矩阵第三行那三个数:

js 复制代码
// 左右转头时,这个向量数学上保持不变;抬头低头必然让它偏转
const up = {
  x: 2 * (x * z - y * w),
  y: 2 * (y * z + x * w),
  z: 1 - 2 * (x * x + y * y),
};

以校准那一刻记下的 uRef 为基准,算一个带符号的偏角:

js 复制代码
verticalRaw(pose) {
  const u = normVec(pose.up);
  const c = crossVec(ctl.uRef, u);            // 叉积拿旋转轴
  const sinp = clamp(dotVec(c, ctl.rAxis), -1, 1); // 投影到俯仰轴,剔除歪头
  return (Math.asin(sinp) * 180) / Math.PI;
}

这么一改,怎么戴都不影响了,歪头那部分被投影直接滤掉。当天换上就通了。

上下的正负号我也不猜了:第一次进游戏让用户低一次头,用实际动作确定符号并本地记住,只做一次。用户的动作永远比我的假设可靠。

第二个坑:头一歪就停不下来

最早一版写的规则是"偏转超过阈值走一步,一直偏着就一直走",写的时候觉得挺合理。真机一戴,不到一分钟我就否了,那感觉跟油门踩死一样,小人直接往墙里冲。后来改成偏转、走一步、锁住。锁住之后怎么解锁,这才是麻烦的,我先试的是"回正到中立区",结果戴着眼镜的人根本不知道"正"在哪,头越摆越偏,越急越回不去。最后定的方案:头停稳大约一秒,就把当前姿态当成新零点,自动解锁。不用回任何特定位置,停一下就行,这个"停"字是关键。

这个改动还白捡一个好处:坐姿变了、传感器漂了,它自己就吸收了,手动校准彻底不用。阈值都集中放一张表里,想调哪个改哪个,不用翻代码:

js 复制代码
export const HEAD_TUNING = {
  yawTrigger: 10,       // 左右转头超过 10° 触发
  pitchTrigger: 8,      // 抬头低头超过 8° 触发
  alpha: 0.45,          // EMA 平滑系数,抗抖动
  rescueAfterMs: 1000,  // 停稳 1 秒 → 自动重新定零并解锁
  driftAdaptRate: 0.008,// 中立区内基准缓慢跟随,吸收漂移
};

四、成品什么样

创建 Rokid AIUI 项目一共有三种方式。我们是用 claude code 开发的,所以就选了本地导入,把本地项目导入到 Rokid AIUI 里面。

测试的时候可以选真机模拟。

项目测试没问题后,可以点击构建与提审,然后就可以等待官方人员审核啦,审核通过的话就会上架到智能体商店,失败的话官方人员也会告诉你哪点需要改善,改善完成后重新提交即可。

15 个关卡,最少推箱数从 1 到 36 递增,每关都过了一遍 BFS 求解器确认可解。头控是左右转头走左右、抬头低头走上下,走一步锁定,头停稳一秒自动重新定零。语音可以喊「上」「下」「左」「右」,撤销、重来、选关也都能说。进游戏零点击,进度自动存,重进接着玩,切后台自动暂停。


五、总结

AIUI 上手难度不高。会写小程序的话,写 .ink 几乎没门槛,我第一天就把第一个页面跑在眼镜上了。从第一个页面跑到眼镜上,到 15 关全部做完,前后大概花了两周,大头都花在调头控手感上。

回头想,跟它配合有三条经验。头一条,资料先喂够再提需求。官方 skill、文档、示例仓库、设计规范一次给足,等它学完,这一步省下的返工比花的时间多得多。第二条,报问题要具体。跟它说"不好用"没信息量;说"只能左右走,抬头低头没反应""说一次就报语音识别失败"这种,它基本一次就能定位到根因,真机上碰到的每个异常都值得原样复述。第三条,把逻辑挪出 UI。引擎、头控、页面逻辑都能在 Node 里跑,它就能自己写测试、自己发现回归。

工作日晚上写累了,我会真戴上眼镜推两关。左右转头、抬头低头,几分钟下来脖子松快不少。童年那个机顶盒游戏,就这么回到我日常里了,有点意外。

AIUI Studio(中国站):aiui.rokid.com/

AIUI GitHub项目地址:github.com/jsar-projec...

AIUI Gitee项目地址:gitee.com/jsar-projec...

AIUI Skil:github.com/jsar-projec...

AIUI Demo案例:github.com/jsar-projec...

相关推荐
excel2 小时前
前端加密的作用与使用场景
前端
计算机魔术师3 小时前
纽约时报版权诉讼披露:微软高管内部称训练 AI 是人类历史上最大规模劳动窃取
前端
去伪存真3 小时前
大模型的参数量为什么那么大?
前端·人工智能
IT_陈寒3 小时前
Java空指针这次真把我坑惨了
前端·人工智能·后端
八荒启·交互动画5 小时前
# Web特效020—让 Web 特效真正动起来:时间循环应该怎么接
前端·webgl·网页特效·八荒启-交互动画·八荒启
动恰客流统计5 小时前
线下零售数字化浪潮下,客流统计的3个核心发展趋势
大数据·前端·人工智能
用户938515635075 小时前
从小米前端面试题,彻底搞懂闭包、作用域链与 useState 惰性初始化
前端·面试
粥里有勺糖6 小时前
视野修炼第133期 | Native 回春了?
前端·github·agent
aichitang20246 小时前
前端小skill
前端·人工智能·算法·ai·前端框架