单文件实现 2048 小游戏的心得:状态、渲染与手势
最近把 2048 写成了一个零依赖的单文件 HTML,双击就能玩,也顺手放到了静态托管上。记录几个实现时的心得。
一、用一维还是二维存棋盘
我用的是 4x4 的二维数组,0 表示空格。这样写滑动合并逻辑最直观:
let grid = [
[2, 0, 2, 4],
[0, 0, 0, 0],
[8, 8, 0, 0],
[0, 0, 0, 0]
];
二维数组还有一个好处:渲染时行列索引和 DOM 结构天然对应,少一层心智负担。
二、四个方向只写一套逻辑
只实现「向左滑」,其余方向通过旋转棋盘复用:
- 右滑:每行反转 → 左滑 → 再反转
- 上滑:棋盘转置 → 左滑 → 转置回来
- 下滑:转置 → 反转 → 左滑 → 反转 → 转置
合并规则记住两点就行:先压缩(去零),再从左到右两两合并(每格一轮只合并一次),最后补零。旋转复用的写法把 bug 集中在一个函数里,调试轻松很多。
三、随机格与胜负判定
每次有效滑动后,在空格子中随机挑一个生成 2(90%)或 4(10%)。结束判定不需要复杂算法:棋盘无空格且横竖相邻都没有相等数字时,游戏结束。
四、渲染:重建比增量更新省事
小游戏场景下,每次滑动后直接清空棋盘容器、按数组重建 16 个格子,性能完全够用,还避免了增量更新时类名、动画状态不同步的坑。数字不同配不同底色,CSS 里用属性选择器或按数值拼类名都可以。
五、手势与键盘都要支持
桌面用方向键 + WASD,移动端用 touchstart/touchend 的位移差判断滑动方向(阈值 24px 左右,太小容易误触)。另外记得在 touchmove 上 preventDefault,避免页面跟着滚动。
六、单文件的工程意义
HTML/CSS/JS 全内联、无外部依赖,意味着:离线可玩、随处可托管、别人拿到文件就能跑。对于教学演示和作品展示来说,这种「一个文件即产品」的形态反而最省心。
写完最大的感受是:2048 的核心状态机不到一百行,难的从来不是算法,而是把交互细节(动画、手势、边界情况)打磨顺。这也是单文件小游戏最适合练手的原因。
- 点赞
- 收藏
- 关注作者
评论(0)