贪拉蛇是一款运行在抖音互动空间的移动端 H5 游戏,融合了贪吃蛇骨架与拼图填充玩法。玩家操控一条贪拉蛇在地图上移动,用蛇身和吐块填充目标图形区域,通关挑战。
- 移动填充:蛇身经过目标格即为填充
- 吐块填充:双击/点击 A 键,从蛇尾放下绿色方块,用于填充够不到的格子
- 批量吐块:蛇尾在目标区域内时,自动连续吐块填充一整段
- 资源收集:收集金色菱形资源块可以增加蛇长
📦 零外部依赖 · 单 HTML 文件 · 纯前端 · 离线运行
| 层 | 方案 |
|---|---|
| 渲染 | Canvas 2D + requestAnimationFrame(60fps) |
| 音频 | Web Audio API(SoundSynth 自包含合成器) |
| 样式 | CSS3(Flexbox + Grid + 响应式媒体查询) |
| 持久化 | localStorage(游戏进度存档) |
| 构建 | 无构建,纯手写单文件 |
| 依赖 | 零第三方运行时依赖 |
snake/
├── index.html # 主游戏文件(HTML+CSS+JS 全部内联)
├── PRD.md # 产品需求文档
├── README.md # 项目说明文档(本文档)
├── 互动空间创作.md # 互动空间适配规范
├── 优化清单.md # 适配优化清单与自检报告
├── 功能测试.md # 功能测试用例
├── test.html # 原型参考(历史文件)
├── package.json
└── vite.config.js # 仅开发热更新使用
| 模块 | 职责 | 关键实现 |
|---|---|---|
| 关卡系统 | 5 个关卡的数据、目标区域、初始蛇位 | LEVELS 数组,loadLevel() 初始化 |
| 移动系统 | 蛇的自动前进 + 方向控制 | tryMove() 时间守卫驱动,320ms 间隔 |
| 填充系统 | 蛇身填格、吐块填格、批量吐块 | TARGET Set + spitBlocks Map 双状态管理 |
| 特效系统 | 粒子、脉冲波纹、震屏、残影、连击飘字 | fx 全局对象,updateEffects() 每帧更新 |
| 音效系统 | 合成音效 + BGM 排程 | SoundSynth 类,Web Audio API 合成 |
| 结算系统 | 通关/失败结算面板 + 5 级称号 | showSettleScreen() 动态生成 |
| 教程系统 | 帧动画剧本 + 交互式教学 | IIFE 闭包,13 帧 SCRIPT 数组驱动 |
| 存档系统 | 关卡解锁进度持久化 | localStorage + snake_unlock 前缀 key |
蛇在网格上以 320ms 间隔自动前进(requestAnimationFrame 驱动)。玩家可以通过以下方式控制转向:
- 触屏滑动:在屏幕上滑动(阈值 10px)改变方向
- DPad 按键:掌机外壳的十字键
- 键盘:方向键 / WASD
- 双击吐块:屏幕双击 / 空格 / Enter / A 键
方向保护:系统禁止 180° 掉头(如向右时不能直接向左),防止蛇立即撞到自己。
关卡目标图形由一组网格坐标定义(TARGET Set)。填充有两种方式:
- 蛇身经过:蛇头移动到目标格时自动填充,触发绿色脉冲波纹 + 粒子特效
- 吐块填充:双击/空格/Enter 从蛇尾放下一个绿色方块,方块落在目标格内即填充
通关判定(双约束):
- 所有目标格都已被填充(蛇身或吐块覆盖)
- 蛇身和吐块不占用任何非目标格
| 条件 | 说明 |
|---|---|
| 撞墙 | 第 2-5 关:直接 Game Over |
| 撞自己 | 第 2-5 关:直接 Game Over |
| 步数超限 | 达到关卡步数上限 |
| 时间耗尽 | 第 2-5 关有倒计时限制 |
第 1 关(热身)撞墙/撞身仅震动,不会死亡,帮助玩家适应操作。
| 关卡 | 网格 | 目标格数 | 步数上限 | 时间限制 | 特点 |
|---|---|---|---|---|---|
| 1·热身 | 12×12 | 5 格十字 | 99 | 无 | 教学关,无死亡 |
| 2·进阶 | 14×14 | 33 格粗十字 | 400 | 120s | 首次引入资源块 |
| 3·T 型 | 14×14 | 36 格 T 型 | 320 | 100s | 复杂形状 |
| 4·矩形 | 14×14 | 45 格实心矩形 | 280 | 80s | 大面积填充 |
| 5·炼狱 | 14×14 | 56 格大矩形 | 260 | 60s | 高压限时 |
- 粒子爆发:收集资源、填充目标、连击时触发
- 脉冲波纹:填充成功时从目标格扩散的绿色环形波
- 蛇头残影:最近 8 帧的蛇头轨迹(红色渐隐)
- 屏幕震动:碰撞时震屏 + 设备振动
- 濒死滤镜:步数或时间接近上限时,屏幕变红 + 心跳音效
- 连击飘字:连续吐块填充多格时显示"不错/漂亮/完美"
使用 Web Audio API 合成所有音效,零音频文件:
| 音效 | 触发 | 合成方式 |
|---|---|---|
| click | 蛇每走一步 | square 700Hz, 40ms |
| glissando | 转向 | triangle 200→650Hz 滑音 |
| success | 填充目标格 | 三连音 523/659/784Hz |
| bump | 碰撞 | sawtooth 120→60Hz + 白噪声 |
| winFanfare | 通关 | square 上行琶音 C5→E5→G5→C6 |
| loseSound | 失败 | 下滑 400→100Hz + 低频 80Hz |
| collect | 吃金色资源 | 双升调 880→1108Hz |
BGM 分三档:第 1 关 135bpm C 大调,第 2-3 关 150bpm A 小调,第 4-5 关 180bpm A 小调。
整体设计致敬 GameBoy 像素掌机:
- 外壳:暗紫色机身
#2a2332,圆角边框,像素装饰灯,螺丝装饰 - 屏幕:内凹屏幕区域,玻璃反光 CSS 伪元素,棋盘格暗色背景
- DPad:十字方向键 + A/B 红色/蓝色按钮
- Canvas:60fps 渲染,蛇身 HSL 渐变色,头部带跟随方向的眼睛
- 响应式:适配 320px ~ 480px 屏幕宽度,矮屏/小屏/超小屏三档缩放
互动空间合规(互动空间创作.md)
- ✅ 单文件交付,
index.html位于根目录 - ✅ 零网络请求,零外部资源引用
- ✅ 无
alert/confirm/prompt/print - ✅ 无站外跳转或
<iframe> - ✅ 事件绑定使用
addEventListener - ✅ 所有弹层为 DOM 自绘
- ✅ 音频通过用户手势解锁
- Canvas 2D 像素渲染,无过多重绘
- 粒子数量动态控制,不会无限累积
requestAnimationFrame驱动动画循环- Web Audio 实时合成,零音频文件加载
直接使用任意 HTTP 服务器打开 index.html:
# Python
python -m http.server 8080
# Node.js
npx serve .然后浏览器访问 http://localhost:8080 即可。
本游戏为纯前端单文件,无需构建步骤。将 index.html 直接上传至抖音互动空间即可。
如需要打包为 .zip:
cd snake/
zip -r 贪拉蛇.zip index.html
⚠️ 确保index.html在压缩包根目录,不要多包一层文件夹。
- 首次打开会显示新手引导教程
- 支持触屏滑动操控(推荐)和键盘操控
- 点击屏幕左侧关卡名称可以跳关
- 第 1 关为教学关,撞墙不会死亡
| 阶段 | 内容 |
|---|---|
| V1 基础框架 | 贪吃蛇移动、网格渲染、关卡系统 |
| V2 填充玩法 | 目标区域、蛇身填充、吐块填充 |
| V3 完整关卡 | 5 个关卡设计、双约束通关判定 |
| V4 音频系统 | SoundSynth 合成器、三档 BGM |
| V5 交互教程 | 帧动画剧本、3 次用户交互教学 |
| V6 视觉效果 | 粒子系统、脉冲波纹、濒死滤镜、连击特效 |
| V7 掌机外壳 | GameBoy 风格 CSS、DPad、响应式布局 |
| V8 互动空间适配 | 错误兜底、弹层管理、进度存档、横屏提示 |
| V9 丝滑优化 | 移动平滑插值、触摸灵敏度、响应速度调优 |
项目为个人作品,欢迎提出 Issue 或改进建议。