从零写一个 2048:布局、合并与动画
为什么用原生 JS 写一遍
2048 规则简单,但很适合练习状态管理与 DOM 动画。最近用一个小游戏练手,目标是不引入框架、不依赖外部资源,单个 HTML 文件即可运行。
一、棋盘用绝对定位,而不是表格
背景格与方块分开渲染:背景是固定的 16 个格子,方块则是独立的绝对定位元素。每个方块保存行、列与数值,渲染时把行列换算成 left/top。这样移动时只需要改坐标,DOM 结构不会重排,过渡也更稳定。
二、移动与合并:先压缩,再合并,再压缩
以向左为例,按行取出所有方块,保持顺序。用一个 target 指针指向下一个可放置的位置:如果前一个方块数值相同且本回合未合并过,就合并并加倍;否则放到 target 位置。合并过的方块要打标记,避免一次移动里连续合并三次。四个方向只需把行列互换、必要时反转顺序,就能复用同一套逻辑。
三、动画冲突:位移用 left/top,缩放用 transform
最初把位移也放在 transform 上,结果新方块的出现动画会覆盖位移,方块瞬间跳到左上角。解决办法是分工:位移过渡交给 left/top,transform 只负责 pop 和 merge 的缩放。两个属性互不干扰,动画就正常了。
四、怎么自测
用无头 Chrome 打开页面,连续派发 80 次方向键,然后检查三件事:方块数量不超过 16、所有方块的 left/top 组合唯一、控制台没有异常。再加一条:页面不能引用任何外部脚本或图片,避免离线或跨域问题。
五、部署
把 index.html 放到 ECS 的 /var/www 下,用 nginx 做静态托管,开放 80 端口即可公网访问。整个过程不需要构建,也没有额外依赖,适合作为最小可用的上线练习。
小结
这个小项目的关键不在算法,而在边界:动画属性不要互相覆盖,合并标记要及时清理,渲染要以数据为准而不是直接操作 DOM。把这三点处理好,代码量并不大,但可维护性会好很多。
- 点赞
- 收藏
- 关注作者
评论(0)