Files
Genarrative/docs/technical/RUNTIME_INPUT_DEVICE_ABSTRACTION_2026-05-10.md

64 lines
3.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 运行态输入设备抽象层 2026-05-10
## 背景
拼图运行态接入 mocap 后,鼠标/触控和 mocap 曾各自维护一套选择、坐标换算和拖拽提交逻辑。这样会让新设备只能在单个玩法里打补丁,也容易出现同一动作在不同设备下语义不一致的问题:例如 mocap `grab` 只触发选中,而不是像鼠标按住一样持续拖拽。
后续运行态还会接摇杆、键盘、体感、摄像头手势等输入来源,因此输入设备接入必须收口到全项目通用层。
## 决策
新增 `src/services/input-devices/` 作为前端运行态通用输入设备抽象层:
1. `runtimeDragInputController` 只维护设备无关的拖拽会话状态机。
2. `runtimeInputGeometry` 只处理 client 坐标、归一坐标、元素边界和网格命中换算。
3. 设备适配层把鼠标、触控、mocap 等输入归一为 `press / move / release / tap / drop`
4. 玩法组件负责把通用输入点解释成自己的目标对象和落点,不把拼图、方洞或大鱼等玩法规则写进输入层。
## 当前接入
`useMocapInput` 解析 mocap `hands[].landmarks` 时应优先用 MediaPipe 21 点里的 `wrist / index_mcp / middle_mcp / ring_mcp / pinky_mcp` 加权计算掌心派生点;少于 3 个掌心关键点时才回退到 `wrist` 或直出 `hand.x/y`。这样运行态光标不会直接贴在腕部或指尖。
拼图运行态已接入该层:
- 鼠标/触控 `pointerdown / pointermove / pointerup` 进入同一个 drag controller。
- mocap `grab` 进入同一个 drag controller并强制使用持续拖拽语义。
- mocap 光标按 60Hz 插值更新 UI 位置,并在拖拽中用插值后的当前点持续驱动输入层,避免输入包帧率低或抖动时出现明显跳变。
- 合并大块由拼图运行态把手部坐标命中到任一成员拼块;本地拼图运行时再按 `mergedGroupId` 执行整组平移。
## 调试模式
前端全局调试模式统一通过 `src/config/debugMode.ts` 判断。默认跟随 Vite 开发态:`import.meta.env.DEV` 为真时开启,生产构建默认关闭;如需显式覆盖,可设置 `VITE_DEBUG_MODE=true``VITE_DEBUG_MODE=false`
拼图运行态的 mocap 调试面板只在全局调试模式下渲染。面板默认折叠,只保留一行连接状态,展开后才显示动作、手势、解析告警和原始包预览,避免开发诊断信息遮挡拼图棋盘和底部操作。
## 接入规则
新玩法或新设备接入时遵循以下边界:
1. 输入层可以知道设备类型和几何换算,但不能知道玩法业务规则。
2. 设备适配层只负责把原始输入转换成通用输入事件。
3. 玩法壳层负责从通用输入点解析本玩法目标,例如拼块、洞口、角色或实体。
4. 玩法壳层负责决定 drop 后调用哪个本地运行态函数或后端接口。
5. 需要取消输入时优先按 `inputId` 取消,避免 mocap 丢帧误伤正在进行的鼠标/触控会话。
## 验证
基础抽象层验证:
```bash
npm run test -- src\services\input-devices\runtimeDragInputController.test.ts src\services\useMocapInput.test.ts
```
拼图接入验证:
```bash
npm run test -- src\components\puzzle-runtime\PuzzleRuntimeShell.test.tsx
```
跨平台入口缺失作品兜底验证:
```bash
npm run test -- src\components\rpg-entry\RpgEntryFlowShell.agent.interaction.test.tsx -t "missing puzzle public detail returns to platform home"
```