Skip to content

gainbandwidth/NeckSnake

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NeckSnake

体感小游戏:

  • 检测人头 上 / 下 / 左 / 右 转动
  • 用头部方向控制贪吃蛇运动轨迹

前端技术栈

  • Vite
  • TypeScript
  • 原生 DOM + Canvas
  • MediaPipe Tasks Vision(PoseLandmarker)

运行

npm install npm run dev

浏览器打开 http://localhost:5173

使用步骤

  1. 点击 1. 打开摄像头
  2. 保持坐正、肩膀入镜,点击 2. 校准中立姿态
  3. 点击 3. 开始/重开
  4. 通过头部上下左右转动控制蛇移动

游戏参数

  • 网格数量控制:可设置网格列数(12-60)和行数(10-40)
  • 边界穿越:开启后,蛇碰到边界会从另一侧出现
  • 速度控制:4-14 格/秒,支持运行中动态调节

项目目录与功能

1) 核心源码目录

src/ ├─ main.ts # 应用入口:UI 组装、事件绑定、状态联动 ├─ styles.css # 页面样式 ├─ motion/ │ └─ HeadMotionController.ts # 头部动作识别(摄像头、校准、方向判定) └─ snake/ └─ SnakeGame.ts # 贪吃蛇核心逻辑(移动、碰撞、参数更新) 

2) 运行与配置目录

. ├─ index.html # 挂载根节点与前端入口脚本 ├─ package.json # 依赖与 npm scripts ├─ tsconfig.json # TypeScript 配置 ├─ vite.config.ts # Vite 构建/开发配置 ├─ public/models/ # 本地模型与 wasm 资源 │ ├─ pose_landmarker_lite.task │ ├─ hand_landmarker.task # 当前玩法未使用,可保留 │ └─ wasm/ └─ README.md 

3) 构建产物与依赖目录

dist/ # 构建产物(npm run build 生成) node_modules/ # npm 依赖 

文件级功能说明

  • src/main.ts

    • 构建页面 UI
    • 驱动三步流程:打开摄像头 -> 校准 -> 开始游戏
    • 接收 HeadMotionController 输出方向并驱动 SnakeGame
    • 管理可调参数(网格、边界穿越、速度)
  • src/motion/HeadMotionController.ts

    • 初始化 MediaPipe PoseLandmarker
    • 读取摄像头视频帧并输出方向事件
    • 处理校准、跟踪状态、抗抖/防误判逻辑
  • src/snake/SnakeGame.ts

    • 维护蛇、食物、分数、时钟
    • 实现可配置网格、边界穿越、速度
    • 支持运行中参数更新(必要时重启当前局)

设计原理

1) 模块解耦

  • 动作识别游戏逻辑 完全分离
  • HeadMotionController 只负责给出方向事件,不关心蛇怎么移动
  • SnakeGame 只关心方向输入,不关心方向是来自键盘还是摄像头

好处:

  • 识别算法可以单独迭代,不破坏游戏规则
  • 未来替换识别源(比如手机 IMU)时,游戏层几乎不用改

2) 轻量化优先

  • UI 采用原生 DOM
  • 游戏采用原生 Canvas
  • 只保留 PoseLandmarker 这一条识别链路

好处:

  • 首屏更快,依赖更少
  • 可控性高,排查误判更直接

3) 参数化设计

  • SnakeGameOptions 统一承载玩法参数:colsrowswrapAroundspeedMs
  • updateOptions() 支持运行中修改并返回结果(是否重启、是否速度变化)

好处:

  • 主界面控制项可以无缝映射到游戏内核
  • 后续新增难度档位不需要改底层架构

优化过程

识别效果逐步优化的关键路径。

阶段 A:基础版本

思路:

  • 使用鼻尖相对基线偏移,超过阈值即触发方向

问题:

  • 对抖动敏感
  • 中立附近容易误判
  • 连续动作时容易反复触发

阶段 B:稳定性增强

引入策略:

  • 候选方向稳定帧确认(不是单帧即触发)
  • 上下左右阈值不对称,up 阈值更严格
  • 中立附近忽略微动

收益:

  • 减少了“中立误判向上”
  • 降低单帧噪声造成的误触发

代价:

  • 响应速度变慢

阶段 C:跟手性优化(当前主版本)

为解决“迟缓”与“偶发不准”,改成以下组合:

  1. 相对肩膀中心坐标
  • 不再只看鼻尖绝对位置,而是看 nose - shoulderCenter
  • 抵抗人体整体在画面中的平移漂移
  1. 低延迟平滑(EMA)
  • dx/dy 做轻量平滑
  • 保留跟手性同时抑制抖动
  1. 轴向主导判定
  • 只有 X 或 Y 方向足够主导才判为左/右或上/下
  • 降低斜向动作造成的串向误判
  1. 动态触发门槛
  • 高置信方向可 1 帧确认
  • 普通置信方向需 2 帧确认
  • 最小触发间隔按“同方向/异方向”区分
  1. 校准与漂移补偿
  • 校准改为多帧采样平均,不用单帧
  • 中立区域内缓慢更新基线,吸收坐姿慢漂移

综合效果:

  • 响应更快(方向切换更敏捷)
  • 中立区更稳(误判明显下降)
  • 长时间游玩不容易“越玩越偏”

游戏参数控制

1) 网格数量控制

  • cols/rows 从常量改为运行时配置
  • 网格变更时重建棋盘并重置当前局,防止旧坐标越界

2) 边界穿越

  • 在 tick 中增加 wrapAround 分支
  • 关闭时撞墙结束;开启时进行坐标环绕映射

3) 速度控制

  • 把速度改成 speedMs 参数
  • 运行中改速度时只重启计时器,不重置当前局

模型文件说明

默认优先读取本地模型路径(已包含在 public/models):

  • public/models/pose_landmarker_lite.task
  • public/models/wasm/*

本地文件缺失时会自动回退到 CDN。

About

体感贪吃蛇小游戏:用头部方向控制贪吃蛇运动轨迹

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors