为社团活动写了一个「扫码即玩」的多人贪吃蛇

大屏投映整局对战,手机扫一下码就能加入。不用装 App、不用注册、不用等加载——难点全在「现场」这两个字上。

2026-09-12·6 分钟阅读·任增浩

社团活动需要一个能把人留在摊位前的东西:大屏上放着一局正在进行的对战,路过的人掏出手机扫一下码就能进来玩。不能装 App,不能注册,不能等加载。于是就做了这个多人贪吃蛇。

双端结构:大屏负责看,手机负责搓

手机只上行一个方向指令,不上传位置。这一点在现场很关键:几十台手机同时连着 WiFi,如果每台手机都把自己算出来的位置发上来,网络和服务器都吃不消。

现场必须提前想好的几件事

1. 人少的时候不能冷场

机器蛇会在人数不足时补位。它们有独立的决策间隔,还带一套「体力」设定——每隔几秒掉一段长度,长度缩到阈值以下就自然退场,所以不会出现机器人无限长大霸榜的情况。

2. 死了还能接着玩

每条蛇三条命,死亡后 1.2 秒复活,并给 2 秒无敌时间。社团现场最怕的就是「一进来就撞死,然后尴尬离场」,三条命刚好够新手把操作摸熟。

3. 带宽要算着花

地图是 362×226 格,几十条蛇在上面游动。如果把完整世界状态每帧广播给每个客户端,流量会非常难看,所以做了裁剪:只下发以你为中心、视野范围内的高精度身体;视野外分档降级处理;同时严格保证「视野和碰撞范围内至少要把粗身体补全」——绝不能出现撞上一条看不见的蛇。

食物也不全量推,只下发一定半径内的,另外按客户端错峰做周期性对账,保证重新进视野的时候不会缺食物。

4. 弱网和旧缓存

现场 WiFi 什么状况都有,所以心跳时间放宽,避免被误判掉线。传输上直接走 WebSocket,跳过 polling 握手省两个 RTT;压缩关掉,因为在 2 核机器上压缩的 CPU 开销比省下来的流量更贵,还额外增加延迟。

const io = new Server(server, {
  transports: ["websocket"],   // 跳过 polling 握手
  allowUpgrades: false,
  perMessageDeflate: false,    // 关压缩:CPU 比流量更贵
  httpCompression: false,
  pingInterval: 30000,         // 心跳放宽,弱网不易误判
  pingTimeout: 45000
});

页面一律 no-store,静态资源用 no-cache——手机端刷新即得新版,不会出现「手机还跑着旧 JS、和服务器新协议对不上」的情况;没改动的资源走 304,几乎不耗流量。

手感

操作是摇杆平滑转向,不是四方向硬拐:基础速度 11 格/秒,按住加速 1.85 倍,转向有最大角速度限制,所以蛇走的是弧线而不是直角。食物带小范围磁吸,蛇头靠近就会被吞掉,省得新手为了对准食物而烦躁。

部署

游戏跑在一台云服务器上,通过 Cloudflare Tunnel 挂到 wxekre.cn/game/。为什么不直接解析到服务器 IP,原因写在另一篇里:《把个人站和个人服务一起挂上 Cloudflare》。

工程实践Node.js
← 返回首页 进入游戏演示 →