第 8 周:2048 网页游戏逻辑与最终验收
本周目标
本周完成后,应能够:
- 在第 7 周静态页面基础上接入第 6 周的 2048 核心逻辑
- 使用 JavaScript 数据驱动 DOM 渲染棋盘
- 使用键盘方向键控制棋盘移动
- 正确处理有效移动、无效移动、随机生成数字和重新开始
- 正确累计当前分数,并使用本地存储保存最高分
- 判断胜利和失败状态,避免游戏结束后继续修改状态
- 为核心规则设计并执行明确的测试用例
- 整理代码结构、Git 提交、README 和 GitHub 项目说明
- 独立讲解 2048 的状态、移动算法和渲染流程
项目基础
本周从第 7 周完成的 2048 静态页面继续开发,不重新设计页面结构。第 7 周的 HTML 和 CSS 作为视觉基础,本周重点是 JavaScript 状态管理、DOM 渲染、交互流程、测试和最终交付。
需要掌握的知识点
状态建模
- 使用二维数组表示 4×4 棋盘
- 使用变量保存当前分数、最高分和游戏状态
- 区分数据状态和页面显示
- 页面只根据数据渲染,不把 DOM 当作游戏状态来源
- 设计初始化、移动、生成数字、胜负判断和重新开始的状态流转
逻辑复用
- 复用第 6 周的
moveLeft()、moveRight()、moveUp()和moveDown() - 复用第 6 周的
hasTarget()进行胜利判断 - 复用第 6 周的
isGameOver()进行失败判断 - 复用空位查找、随机索引和棋盘复制函数
- 保持核心移动规则不变,避免在 DOM 接入阶段改坏算法
DOM 渲染
- 根据棋盘二维数组生成或更新 16 个格子
- 根据数字值设置方块文本和样式类
- 当前分数、最高分和状态提示由数据统一驱动
- 渲染函数只负责显示,不负责修改游戏规则
- 处理数字位数变化时的字体大小和居中问题
输入与游戏流程
- 使用键盘方向键触发四个方向移动
- 根据移动结果中的
changed判断是否生成新数字 - 无效移动不生成新数字、不增加分数
- 重新开始时重置棋盘、当前分数和游戏状态
- 游戏结束后阻止继续移动
- 避免重复绑定键盘事件
分数与本地存储
- 仅在数字合并时增加当前分数
- 每次合并增加新方块对应的数值
- 当前分数变化后更新页面显示
- 使用
localStorage保存和恢复最高分 - 首次访问、存储值不存在或存储值异常时使用合理默认值
- 重新开始不清空最高分
胜负状态
- 出现 2048 方块时显示胜利状态
- 棋盘填满且不存在可合并数字时显示失败状态
- 胜利和失败提示应显示在第 7 周预留的状态区域
- 游戏结束后按钮仍可重新开始
- 胜负判断应发生在有效移动并生成新数字之后
测试与调试
- 为移动函数准备确定的棋盘输入和预期输出
- 分别测试正常情况、边界情况和无效操作
- 测试分数累计、最高分恢复、胜利、失败和重新开始
- 记录实际结果与预期结果的差异
- 修复问题后重新执行全部规则测试
- 最终提交前移除临时测试入口和调试日志
代码与项目整理
- 将状态、移动、渲染、输入和存储逻辑合理拆分
- 函数和变量名称能够表达实际用途
- 删除重复代码、无用资源和临时文件
- README 包含项目介绍、功能、运行方式、操作方法和截图
- 最终代码推送至 GitHub
必做任务
- 复查第 7 周页面结构,确认分数、棋盘、状态提示和按钮都有可操作的 DOM 标记。
- 整理第 6 周核心函数,复制或模块化接入第 8 周项目。
- 建立游戏状态对象或状态变量,保存棋盘、当前分数、最高分和游戏状态。
- 实现
renderBoard(),根据二维数组更新 4×4 棋盘。 - 实现
renderScore()和renderStatus(),更新分数和状态提示。 - 使用键盘方向键调用四向移动函数。
- 仅在有效移动后生成新数字,并重新渲染页面。
- 实现当前分数累计,并保证无合并时分数不增加。
- 使用
localStorage保存并恢复最高分。 - 实现重新开始按钮,重置棋盘、当前分数和状态提示。
- 实现胜利和失败判断。
- 执行规则测试、交互测试和刷新恢复测试。
- 整理代码、README、截图和 Git 提交记录。
- 准备一次 5 分钟项目讲解。
功能验收
- 使用 HTML、CSS 和原生 JavaScript 开发,未使用游戏框架
- 使用第 7 周静态页面作为视觉基础
- 使用 4×4 棋盘,通过键盘方向键控制移动
- 开始游戏时随机生成两个数字方块
- 仅在有效移动后于空白位置生成新数字
- 相同数字按照 2048 规则合并并正确累计分数
- 支持胜利、失败判定和重新开始
- 使用本地存储保存并恢复最高分
规则测试
-
[2, 2, 2, 2]向左移动后得到[4, 4, 0, 0] -
[4, 4, 8, 0]向左移动后得到[8, 8, 0, 0] -
[2, 2, 4, 0]向左移动后得到[4, 4, 0, 0],不能连续合并为 8 -
[4, 0, 4, 4]向左移动后得到[8, 4, 0, 0] - 向右、向上、向下移动时遵守相同合并规则
- 仅移动位置但未合并时,分数不增加
- 棋盘状态没有变化时,不生成新数字
- 棋盘填满且不存在可合并的相邻数字时,游戏失败
- 出现 2048 方块时,显示胜利状态
- 重新开始后,棋盘和当前分数正确重置
- 刷新页面后,最高分能够正确恢复
工程验收
- 使用 Git 管理项目,提交记录能够体现主要开发过程
- 最终代码已推送至 GitHub
- 仓库包含项目介绍、运行方式、操作说明和截图
- HTML、CSS 和 JavaScript 文件职责清晰
- 核心移动和合并逻辑已拆分为独立函数
- DOM 渲染、事件输入、本地存储和状态判断职责清晰
- 页面无明显错位、遮挡、溢出或控制台报错
- 能够独立讲解棋盘状态、移动合并算法和渲染流程
视觉验收
- 页面仍保持第 7 周蓝湖设计图还原效果
- 动态数字变化不会导致棋盘格子尺寸跳动
- 当前分数、最高分和状态提示变化时布局稳定
- 重新开始和胜负状态不会破坏页面结构
- 桌面端和移动端布局均可正常操作
- 已提供最终页面截图
Git 提交要求
本周至少通过独立提交体现以下开发步骤:
- 接入第 6 周核心移动逻辑
- 建立游戏状态和初始化流程
- 完成棋盘 DOM 渲染
- 完成键盘方向键控制
- 完成分数和最高分逻辑
- 完成胜利、失败和重新开始流程
- 完成规则测试和问题修复
- 完成 README、截图和最终整理
本周产出
- 2048 最终可玩版本
- 完整的规则测试记录
- 最高分本地存储实现
- 最终页面截图
- 包含说明和截图的 GitHub 仓库
- 一份阶段一知识复盘和待补强清单
- 两个阶段项目的口头讲解提纲