Back to home

RiChenyv

bamboo-cicada-3d

千万token以内最好玩的玩具

Stars
1
Language
JavaScript
Created
Aug 16, 2026
Updated
Aug 16, 2026

Introduction

竹知了 · 3D 仿真 🎋

把中国传统玩具「竹知了」(竹蝉)搬进浏览器的 3D 仿真网页游戏:一根竹签串着薄竹片, 搓动竹签让竹片高速旋转切割空气,发出像夏天蝉鸣一样「哇呜——哇呜——」的声音。 转得越快,声音越响、音调越高;慢下来声音变闷、变低,直到自然消失。

全部资源本地化(无 CDN、无外部音频文件),打开即玩。

快速开始

node server.mjs          # 默认端口 8333
node server.mjs 8080     # 自定义端口

浏览器打开 http://127.0.0.1:8333/。同一 WiFi 下手机可直接访问终端打印的 LAN 地址。

需要现代浏览器(Chrome / Edge / Safari,支持 WebGL 与 ES Modules)。 零 npm 依赖:three.js 与 MediaPipe Hands 已 vendor 到 vendor/

玩法

模式规则
自由随便搓,看转速、听声音
持久鸣叫转速 ≥ 12 转/秒算「鸣叫」,连续鸣叫越久分越高;挑战 10 / 20 / 30 / 45 秒徽章
极速冲刺20 秒内冲到最高转速,≥70 转/秒(4200 RPM)评 S

最好成绩保存在 localStorage,刷新不丢。

操作方式(多端)

  • 🖱 鼠标:按住竹签/竹片快速来回拖动 = 搓动;按住空白处拖动 = 旋转视角;滚轮缩放
  • 📱 触摸:同鼠标,单指拖动搓动 / 双指缩放旋转
  • 📳 摇一摇:手机快速摇动给转子加冲击(iOS 首次需点「📳 摇一摇」授权)
  • 📷 摄像头手势(MediaPipe Hands,本地模型):双手反向移动 = 真实滚搓;单手快速来回划 = 划搓
  • 键盘空格 持续滚搓 · R 停转重置 · M 静音
  • ⚡ 「一键助转」按钮适合快速体验

仿真还原点

构造:竹签 + 薄竹片(中心孔、细长叶形、带螺旋桨扭角)+ 中心轴帽 + 叶尖红点, 竹片与竹签固定成一体转子,与真实竹知了一致。

发声原理:竹片每转一圈两次「过风」,声音基频 = 2 × 转速。 Web Audio 实时合成(无任何录音):双失谐锯齿波(丰富谐波)+ 随转速扫频的低通 + 每转一次的幅度调制(「哇呜」颤音)+ 叶片切风噪声 + 掌心搓动摩擦噪声, 转速下降时音调与响度连续衰减至静音。参数平滑采用指数趋近,无爆音。

物理:搓动给转子角速度(棘轮打滑模型——反向搓动只传递部分力矩,来回搓也能提速, 与真实玩法中「回程放松/单向轴承」一致);松手后受空气阻力(高速主导,二次项) 与**轴承摩擦(低速主导,线性项)**衰减,低速静摩擦停转,滑行曲线与真实玩具手感接近。

转速可视化:12 层残影实例(加法混合)+ 高速模糊光斑,转速一眼可辨。

运行与验证

npm test          # Node 单元测试:物理衰减/棘轮/搓动识别/音频参数映射(16 项)
npm run verify    # 真实浏览器 E2E:音频随转速变化、物理、交互、玩法、存档、残影、移动端布局(19 项)

test/verify.mjs 基于零依赖 CDP 客户端(test/cdp.mjs,Node ≥ 20 原生 WebSocket)驱动 本机 Edge/Chrome headless。受限环境无法直接拉起浏览器时,可先手动启动:

msedge --headless=new --remote-debugging-port=9223 --user-data-dir=<tmp> about:blank
CDP_CONNECT_ONLY=1 npm run verify

验证截图输出到 shots/desk_idle / desk_mid / desk_fast / mobile)。

目录结构

index.html          页面骨架(importmap + HUD)
css/style.css       响应式样式(桌面侧栏 / 移动端底部面板,深色竹林风)
js/config.js        全局常数 + 转速→音频参数纯函数
js/physics.js       转子物理(搓动棘轮 + 空气/轴承阻力衰减)
js/audio.js         Web Audio 实时合成引擎
js/rub-detect.js    手势搓动识别(纯逻辑,可单测)
js/rub.js           输入中枢(指针/键盘/摇一摇/手势桥接)
js/gesture.js       MediaPipe Hands 摄像头手势
js/game.js          挑战玩法 + 最好成绩(localStorage)
js/toy.js           3D 场景(竹签/竹片/残影/光斑/灯光)
js/textures.js      程序化竹材质(Canvas 生成)
js/main.js          装配与主循环(含 window.__zzl 调试接口)
vendor/three/       three.module.js + three.core.js + OrbitControls
vendor/mp/          MediaPipe Hands(模型与 wasm)
server.mjs          零依赖静态服务器
test/               单元测试 + E2E 验证 + CDP 客户端