大一计算机专业全栈工程师学习路线
路线说明
本路线面向已掌握 C 语言和数据结构的计算机专业大一学生,计划通过约 10 个月的系统学习,逐步形成 Java 后端与 Vue 前端的全栈开发能力,并为实习求职做好准备。
README 仅展示整体路线。每个阶段的知识安排、练习任务、验收标准和执行计划,请查看对应阶段的详细计划。
路线总览
| 阶段 | 学习方向 | 预计时间 | 验收项目 | 详细计划 |
|---|---|---|---|---|
| 阶段一 | 前端入门 | 2 个月 | 官网还原、2048 游戏(均提供蓝湖设计图) | 查看计划 |
| 阶段二 | Java 基础 | 2-2.5 个月 | 控制台版学生信息管理系统 | 查看计划 |
| 阶段三 | 前端工程化 | 1.5-2 个月 | 后台管理前端项目 | 查看计划 |
| 阶段四 | 后端进阶与全栈整合 | 3-4 个月 | 全栈个人博客系统 | 查看计划 |
| 阶段五 | AI Agent 提效 | 持续学习 | 使用 AI Agent 完成项目迭代 | 查看计划 |
阶段一:前端入门
- 核心目标:理解网页结构、样式与交互,能够使用原生前端技术完成基础项目
- 技术方向:HTML、CSS、JavaScript、浏览器开发者工具
- 验收项目:根据提供的官网蓝湖设计图完成纯静态页面还原;使用原生 JavaScript 实现 2048 游戏,并根据对应蓝湖设计图完成界面还原
- 详细计划:stage-1/PLAN.md
阶段二:Java 基础
- 核心目标:建立面向对象思维,掌握 Java 核心语法,并能够操作关系型数据库
- 技术方向:Java SE、Maven、JDBC、MySQL、Git、Linux 基础
- 验收项目:控制台版学生信息管理系统
- 详细计划:stage-2/PLAN.md
阶段三:前端工程化
- 核心目标:掌握组件化与模块化开发方式,能够独立开发现代前端应用
- 技术方向:Node.js、Vite、Vue 3、Vue Router、Pinia、Axios、Element Plus
- 验收项目:使用 Mock 数据的后台管理前端项目
- 详细计划:stage-3/PLAN.md
阶段四:后端进阶与全栈整合
- 核心目标:掌握主流 Java Web 开发技术,完成前后端分离项目及部署
- 技术方向:Spring Boot、MyBatis-Plus、Redis、JWT、Docker、Nginx
- 验收项目:前后端分离的全栈个人博客系统
- 详细计划:stage-4/PLAN.md
阶段五:AI Agent 提效
- 核心目标:理解 AI Agent 的基本工作方式,能够将其应用于学习和开发流程,提高交付效率
- 技术方向:提示词编写、上下文管理、任务拆解、工具调用、代码审查、结果验证
- 验收项目:使用 AI Agent 对已有项目完成一次需求分析、开发、调试和文档整理
- 详细计划:stage-5/PLAN.md
求职准备
求职准备贯穿整个学习过程,重点包括算法练习、计算机基础知识复习、项目总结、简历优化和模拟面试。建议从阶段二开始持续积累,在阶段四完成后集中进行实习投递。
阶段一:前端入门
阶段说明
- 学习周期:8 周
- 建议投入:每天 2-3 小时,每周学习 6 天,复盘和休息 1 天
- 前置要求:掌握基本的计算机操作,具备 C 语言和数据结构基础
- 阶段目标:掌握 HTML、CSS 和原生 JavaScript,能够独立完成静态页面和基础交互项目
主要学习资料
HTML 和 CSS 统一参考黑马程序员的《前端 Web 开发 HTML5+CSS3+移动 Web 视频教程》。课程共 200 节,前四周按视频分 P 顺序学习。
视频仅用于学习知识点和页面实现思路,不要求下载课程源码、切图或其他配套素材,也不要求完成视频中的案例项目。HTML/CSS 实践统一使用提供的官网蓝湖设计图及其可导出资源;蓝湖中没有对应效果的知识点,可以使用纯色块和自编文字完成最小练习。
JavaScript 参考视频待定。确定课程后,再把第 6-8 周的知识点映射到具体视频章节。
阶段成果
完成本阶段后,应能够:
- 使用语义化 HTML 搭建结构清晰的网页
- 使用 CSS 完成 PC 端、移动端和响应式布局
- 根据蓝湖设计图独立还原纯静态官网
- 使用 JavaScript 处理数据并实现基础业务逻辑
- 使用 DOM 和事件完成网页交互
- 使用浏览器开发者工具定位常见问题
- 使用 Git 和 GitHub 管理并提交 2048 游戏项目
周计划
| 周次 | 学习主题 | 视频范围 | 本周成果 | 详细计划 |
|---|---|---|---|---|
| 第 1 周 | HTML 与 CSS 入门 | P1-P42 | 完成基础内容页面 | 查看计划 |
| 第 2 周 | CSS 盒模型与布局 | P43-P80 | 完成蓝湖官网的基础组件和局部布局 | 查看计划 |
| 第 3 周 | PC 端网页综合布局 | P81-P130 | 完成蓝湖官网 PC 端主体 | 查看计划 |
| 第 4 周 | CSS3、移动端与响应式 | P131-P200 | 使用蓝湖官网内容完成高级样式与适配练习 | 查看计划 |
| 第 5 周 | 官网蓝湖设计图还原 | 独立项目 | 完成纯静态官网校对与验收 | 查看计划 |
| 第 6 周 | JavaScript 基础 | 参考视频待定 | 完成基础可玩控制台版 2048 | 查看计划 |
| 第 7 周 | DOM、Git 与 2048 网页化 | 参考视频待定 | 接入 DOM,并补充计分与重开 | 查看计划 |
| 第 8 周 | 2048 蓝湖设计图还原与验收 | 2048 蓝湖设计图 | 根据蓝湖设计图完善项目并验收 | 查看计划 |
阶段验收
项目一:官网蓝湖设计图还原
- 根据提供的蓝湖设计图,使用 HTML 和 CSS 完成页面还原
- 不使用前端框架或 UI 组件库
- 本项目不要求使用 Git 或提交至 GitHub
- 详细要求与验收标准见第 5 周计划
项目二:2048 游戏
- 使用 HTML、CSS 和原生 JavaScript 实现完整的 2048 游戏
- 根据提供的 2048 蓝湖设计图完成游戏界面还原
- 使用 Git 管理开发过程,并将项目提交至 GitHub
- 仓库必须包含项目说明文档
- 详细要求与验收标准见第 8 周计划
阶段完成清单
- 完成 HTML/CSS 课程 P1-P200 及对应练习
- 完成纯静态官网并通过验收
- 完成 JavaScript 基础练习
- 掌握 DOM 操作和常用事件处理
- 完成 2048 游戏全部功能和规则测试
- 2048 项目具有清晰、连续的 Git 提交记录
- 2048 项目已推送至 GitHub,并包含完整 README
- 能够独立讲解两个项目的结构和核心实现
附录:知识点参考
以下知识树仅用于查阅和复习,不属于周计划任务,也不纳入阶段验收:
第 1 周:HTML 与 CSS 入门
本周目标
本周完成后,应能够:
- 不依赖模板写出完整的 HTML 文档结构
- 根据内容选择合适的 HTML 标签,而不是全部使用
div - 正确处理图片、链接等资源的路径
- 使用表格展示数据,使用表单收集基础信息
- 使用外部 CSS 为页面设置文字、颜色和基础尺寸
- 使用浏览器开发者工具检查 HTML 结构和 CSS 来源
- 独立完成一个结构完整、样式清晰的内容型页面
学习资料与范围
- 主课程:HTML5+CSS3+移动 Web 视频教程
- 视频范围:P1-P42
| 视频范围 | 学习模块 | 学习结果 |
|---|---|---|
| P1-P15 | 环境、HTML 骨架、排版、图片、路径、链接和多媒体 | 能够搭建基础内容页面 |
| P16-P27 | 列表、表格、表单、div、span 和字符实体 | 能够组织列表、数据和用户输入 |
| P28-P40 | CSS 引入、基础选择器、字体、文本和调试工具 | 能够为页面添加基础视觉样式 |
| P41-P42 | 新闻详情与 CSS 简介案例 | 能够综合运用本周内容 |
需要掌握的知识点
HTML 基础
DOCTYPE、html、head、body的作用- 标签的开始、结束、嵌套、并列和包含关系
- 标题、段落、换行、水平线和文本格式化标签
- 图片的路径、替代文本、宽高和常见加载问题
- 超链接的目标地址、页面内跳转和新窗口打开
- 音频、视频等多媒体标签的基础用法
- HTML 注释及清晰的代码缩进
页面结构
- 有序列表、无序列表和定义列表的适用场景
- 表格的表头、表体、行、单元格及单元格合并
input的常见类型、下拉菜单、文本域、label和按钮div与span的区别header、nav、main、section、article、aside、footer等语义化标签
路径与目录
- 相对路径与绝对路径的区别
- 当前目录、上级目录和子目录的写法
- HTML、CSS、图片和媒体资源的分类存放
- 文件重命名或移动后资源失效的排查方法
CSS 入门
- 行内、内部和外部样式表的区别,项目中优先使用外部样式表
- 标签、类、ID 和通配符选择器
- 使用多个类复用样式
- 字号、粗细、倾斜、行高和字体族
- 文本缩进、对齐、装饰线和颜色
font复合属性的顺序
调试
- 使用 Elements 面板检查标签嵌套和页面结构
- 使用 Styles 面板查看样式来源、覆盖和未生效规则
- 根据控制台或 Network 面板定位资源路径错误
必做练习
- 个人介绍页:包含标题、照片、简介、兴趣列表和相关链接。
- 课程表页面:使用表格展示一周课程,至少包含一次单元格合并。
- 报名表单:包含文本、单选、多选、下拉、文本域和提交按钮。
- 新闻详情页:使用外部 CSS 设置标题、来源、时间、摘要、正文和图片样式。
- 路径练习:将图片分别放在当前目录、子目录和同级资源目录中并正确引用。
本周综合任务
独立完成一个个人博客文章页,包含顶部导航、文章信息、正文、相关链接和页脚。
要求:
- 使用语义化标签组织主要区域
- HTML 与 CSS 分文件存放
- 至少包含图片、列表和链接
- 不复制课程案例的完整代码
- 页面能够直接打开,资源无加载失败
本周产出
- 个人介绍页
- 课程表页面
- 报名表单
- 新闻详情页
- 个人博客文章页
- 一份本周 HTML 标签和 CSS 属性笔记
完成检查
- 能够不参考模板写出完整 HTML 骨架
- 能够根据内容选择合适的 HTML 标签
- 能够正确使用图片、链接、列表、表格和表单
- 能够区分并正确编写相对路径和绝对路径
- 能够使用外部 CSS 和类选择器组织样式
- 能够使用开发者工具定位结构、样式和路径问题
- 已独立完成个人博客文章页
第 2 周:CSS 盒模型与布局
本周目标
本周完成后,应能够:
- 根据页面结构编写准确且易维护的选择器
- 解释 CSS 层叠、继承和优先级导致的样式结果
- 准确计算元素在盒模型中的实际尺寸
- 处理外边距塌陷、内容溢出和父元素高度塌陷
- 使用 Flex 完成导航、两栏、卡片列表和换行布局
- 根据简单截图独立完成一个 PC 端页面布局
学习资料与范围
- 主课程:HTML5+CSS3+移动 Web 视频教程
- 视频范围:P43-P80
| 视频范围 | 学习模块 | 学习结果 |
|---|---|---|
| P43-P52 | 复合选择器、伪类、CSS 三大特性、背景和显示模式 | 能够控制样式作用范围和元素显示方式 |
| P53-P68 | 结构伪类、伪元素、盒模型、版心、溢出、圆角和阴影 | 能够准确控制组件尺寸与视觉效果 |
| P69-P73 | 标准流、浮动和清除浮动 | 理解传统布局方式及其问题 |
| P74-P80 | Flex 组成、轴、对齐、伸缩、换行和案例 | 能够使用 Flex 完成常见布局 |
需要掌握的知识点
选择器与 CSS 规则
- 后代、子代、并集、交集和兄弟选择器
:hover等常见伪类选择器:nth-child()等结构伪类选择器::before、::after伪元素及content- 层叠性、继承性和优先级
- Emmet 的常用 HTML/CSS 快速写法
背景与显示模式
- 背景颜色、图片、重复、位置和缩放
- 背景复合属性及多层背景的基本概念
- 块级、行内和行内块元素的特点
display对元素显示模式的影响
盒模型
- 内容区、内边距、边框和外边距
- 标准盒模型的实际尺寸计算
box-sizing: border-box的作用- 版心宽度和水平居中
- 浏览器默认样式清除
- 内容溢出与
overflow - 相邻外边距合并、父子外边距塌陷及处理方式
- 圆角、盒子阴影和基础卡片效果
布局
- 标准流中的块级和行内元素排列规律
- 浮动元素的特点和典型使用场景
- 清除浮动及父元素高度塌陷
- Flex 容器、项目、主轴和交叉轴
flex-direction、justify-content、align-itemsflex伸缩比例、flex-wrap和多行对齐- Flex 项目的单独对齐和顺序控制
必做练习
- 导航栏:包含默认、悬停和当前选中状态。
- 产品卡片:严格按照给定宽高、内边距和边框完成盒模型计算。
- 新闻列表:处理长标题截断和内容溢出。
- 两栏布局:分别使用浮动和 Flex 实现,并说明两种方式的差异。
- 商品列表:使用 Flex 实现固定间距、自动换行和统一卡片尺寸。
- 问题复现:主动制造并修复外边距塌陷和浮动导致的父元素高度塌陷。
练习涉及图片、图标或具体页面内容时,统一从提供的官网蓝湖设计图中选取,不使用视频课程的配套素材。
本周综合任务
从官网蓝湖设计图中选取一个包含导航、内容列表或卡片的页面区域,完成其 PC 端基础布局。
要求:
- 主体布局使用 Flex
- 尺寸、版心和区域间距以蓝湖标注为准
- 卡片可以换行且尺寸稳定
- 不使用表格布局,不大量使用绝对定位
- 页面不存在内容溢出、遮挡或意外横向滚动
本周产出
- 导航栏、产品卡片和新闻列表组件
- 浮动版与 Flex 版两栏布局
- 外边距塌陷和浮动问题调试记录
- 官网蓝湖设计图局部布局
- 一份盒模型和 Flex 属性笔记
完成检查
- 能够解释层叠、继承和优先级
- 能够准确计算盒模型尺寸
- 能够处理外边距塌陷和内容溢出
- 能够说明浮动后父元素高度塌陷的原因
- 能够使用 Flex 完成单行、多行和两栏布局
- 已独立完成 PC 页面布局综合练习
第 3 周:PC 端网页综合布局
本周目标
本周完成后,应能够:
- 按“分析设计、划分区域、搭建结构、编写样式、对照调试”的流程制作 PC 网页
- 使用版心和公共样式保持多个区域的一致性
- 正确选择相对、绝对和固定定位
- 使用字体图标、精灵图和过渡效果完善页面细节
- 组织重复卡片和公共区域,减少无意义的重复代码
- 使用蓝湖提供的标注和素材完成官网 PC 端主要区域
学习资料与范围
- 主课程:HTML5+CSS3+移动 Web 视频教程
- 视频范围:P81-P130
| 视频范围 | 学习模块 | 学习结果 |
|---|---|---|
| P81-P93 | PC 页面项目制作流程 | 掌握目录、版心、头部、Banner、内容区和页脚的制作方法 |
| P94-P105 | 定位、层叠、精灵图、字体图标、过渡和轮播图 | 能够实现常见悬浮与装饰效果 |
| P106-P119 | PC 项目目录、SEO、头部和底部 | 能够组织项目公共区域与样式 |
| P120-P130 | PC 项目主体区域 | 能够完成较长、多模块的官网页面 |
视频中的项目只用于观察实现步骤,不要求下载课程素材或完成对应案例。所有编码实践均使用提供的官网蓝湖设计图和可导出资源。
需要掌握的知识点
页面分析与组织
- 从截图或设计图识别版心、通栏、公共区域和重复模块
- 先搭建 HTML 结构,再完成布局,最后处理视觉细节
- 按页面区域拆分 CSS,避免选择器互相影响
- 为导航、卡片、标题区和按钮等重复结构提取公共类
- 图片和图标资源的分类、命名和引用
定位与层叠
- 相对定位保留原位置的特点
- 绝对定位的包含块和“子绝父相”
- 固定定位相对视口的行为
z-index生效条件和层叠顺序- 定位居中、角标、悬浮按钮和覆盖文字
- 避免使用绝对定位承担整个页面主体布局
页面细节技术
- CSS 精灵图的定位方式和适用场景
- 字体图标的引入和使用
- 图片与文字的垂直对齐
opacity、光标类型和悬停反馈transition的属性、时长和触发方式- 静态轮播图区域的结构和层叠关系
工程基础
- 项目目录、公共 CSS 和页面 CSS
title、description、keywords等基础页面信息- Favicon 的配置
- Header、导航、搜索、购物车和 Footer 等公共区域
- 长页面中的样式复用和命名一致性
必做练习
- 分析官网蓝湖设计图,整理页面清单、版心、公共区域和重复模块。
- 使用蓝湖导出的 Logo、图片和图标完成官网 Header、导航和 Banner。
- 完成设计图中的主要内容区域、重复卡片和 Footer。
- 根据设计图中的元素完成固定按钮、角标或覆盖文字;设计图没有对应元素时不强行添加。
- 为设计图中具有交互含义的导航、按钮或卡片补充合理的悬停过渡效果。
- 检查官网页面中的重复样式,至少完成一次公共样式整理。
本周综合任务
根据官网蓝湖设计图,完成一个 PC 页面中的 Header、全部主要内容区域和 Footer。
要求:
- 编码前先画页面结构草图
- 不使用视频课程的源码和素材
- 页面资源均来自蓝湖设计图或蓝湖导出文件
- 公共区域和重复卡片样式得到复用
- 版心、布局、间距和对齐符合蓝湖标注
- 能够解释每处定位的参照对象和使用原因
本周产出
- 官网蓝湖设计图页面清单和结构草图
- 官网 PC 端公共头部、主体区域和页脚
- 使用蓝湖元素完成的定位与悬浮效果组件
- 一次公共样式和重复组件整理记录
- 一份 PC 网页制作流程总结
完成检查
- 已完成官网蓝湖设计图要求的 PC 端主要区域
- 页面图片、图标和文字资源均来自蓝湖设计图或导出文件
- 能够正确选择相对、绝对和固定定位
- 能够组织公共样式和重复卡片样式
- 能够从蓝湖设计图中划分结构和布局层次
- 未依赖课程源码或课程配套素材
第 4 周:CSS3、移动端与响应式
本周目标
本周完成后,应能够:
- 使用变换、过渡和关键帧动画实现基础视觉效果
- 解释移动端视口、物理像素、CSS 像素和二倍图
- 使用 rem 或 vw 完成移动端页面适配
- 使用 Less 的变量、嵌套、运算和导入组织样式
- 使用媒体查询处理手机与桌面布局差异
- 理解 Bootstrap 栅格的基本思想,但不依赖它完成阶段项目
- 独立完成一个无横向滚动的响应式页面
学习资料与范围
- 主课程:HTML5+CSS3+移动 Web 视频教程
- 视频范围:P131-P200
| 视频范围 | 学习模块 | 学习结果 |
|---|---|---|
| P131-P144 | 平面变换、转换原点、渐变和案例 | 能够实现常见二维视觉效果 |
| P145-P156 | 3D 变换、关键帧动画和综合案例 | 能够实现基础 3D 与动画效果 |
| P157-P172 | 移动端、rem、flexible 和 Less | 能够使用 rem 组织移动端页面 |
| P173-P184 | vw/vh 移动端布局 | 能够使用 vw 完成移动端适配 |
| P185-P200 | 媒体查询、Bootstrap 和响应式项目 | 能够理解并实现响应式页面 |
视频中的 3D、移动端和响应式案例只用于理解知识点,不要求下载课程素材或还原案例。练习统一选用官网蓝湖设计图中的文字、图片、图标和页面模块。
需要掌握的知识点
变换、过渡与动画
translate、rotate、scale、skewtransform-origin和多重变换的执行顺序- 使用平移实现未知尺寸元素居中
- 线性渐变和径向渐变
- 3D 视距、空间旋转和立体呈现
@keyframes与animation常用属性- 过渡和动画的区别及适用场景
移动端基础
- 屏幕分辨率、物理像素和 CSS 像素
- 视口的概念和标准 viewport 配置
- 二倍图的使用原因和显示方式
- 固定宽度、rem、vw/vh 和响应式方案的差异
- 移动端固定头部、内容避让和点击区域
- 图片在不同屏幕下保持比例的方法
rem、vw/vh 与 Less
- rem 相对于根元素字号的计算方式
- 使用媒体查询改变根元素字号
- flexible 适配方案的基本原理
- vw/vh 与视口尺寸的换算
- Less 变量、嵌套、运算、导入和导出
- 将设计稿尺寸转换为 rem 或 vw 的思路
响应式布局
- 媒体查询的条件和常见断点思路
- 不同宽度下的显示、隐藏、换行和列数变化
- 移动优先与桌面优先的基本区别
- Bootstrap 容器、栅格、断点、全局样式和组件
- 不依赖框架使用原生 CSS 实现响应式布局
必做练习
- 从蓝湖官网中选择图片卡片和图标,完成缩放、旋转或悬停过渡练习。
- 使用蓝湖官网的导航内容完成变换练习;设计图未要求 3D 效果时,只在独立练习文件中验证属性。
- 选取蓝湖官网的一个页面,使用其内容和资源制作移动端适配练习。
- 使用蓝湖官网的卡片或列表,分别练习 rem 和 vw 两种尺寸换算方式。
- 使用媒体查询让蓝湖官网中的导航或卡片区域适配手机与桌面宽度。
- 使用原生 CSS 完成蓝湖官网页面的响应式练习,不使用 Bootstrap。
本周综合任务
使用官网蓝湖设计图中的导航、Banner 和卡片内容,完成一个响应式练习页面。
要求:
- 至少适配手机和桌面两类宽度
- 使用原生 CSS,不使用 Bootstrap
- 页面文字、图片和图标使用蓝湖设计图及其导出资源
- 手机端和桌面端均无意外横向滚动
- 图片比例稳定,文字不遮挡、不溢出
- 卡片列数能随可用宽度合理变化
- 动画只用于必要反馈,不影响内容阅读
本周产出
- 使用蓝湖图片、图标完成的变换与动画练习组件
- 使用蓝湖页面内容完成的 rem 和 vw 适配练习
- 使用蓝湖页面内容完成的媒体查询练习
- 官网蓝湖设计图响应式练习页面
- 一份移动端适配方案对比笔记
完成检查
- 已完成课程 P131-P200
- 能够使用变换、过渡和关键帧动画
- 能够说明视口和二倍图的作用
- 能够使用 rem 或 vw 完成移动端布局
- 能够编写基础媒体查询
- 已独立完成响应式介绍页
第 5 周:官网蓝湖设计图还原与验收
本周目标
本周在前几周实现结果的基础上完成最终校对和交付。完成后,应能够:
- 从蓝湖设计图中读取页面尺寸、颜色、字体、间距、圆角和切图信息
- 在编码前完成页面区域划分、公共结构识别和资源整理
- 使用语义化 HTML、标准流和 Flex 搭建页面主体
- 合理划分公共样式与页面样式,复用重复组件
- 使用设计图对比和浏览器开发者工具定位视觉偏差
- 独立交付一个结构完整、视觉接近设计图的纯静态官网
项目约束
- 使用提供的蓝湖设计图作为唯一视觉标准
- 仅使用 HTML 和 CSS,不使用 JavaScript、前端框架或 UI 组件库
- 本项目不要求使用 Git,也不要求提交至 GitHub
- 必须独立完成,不直接复制现成网站源码
需要掌握的知识点
设计图分析
- 确认页面数量、入口、目标尺寸和页面之间的关系
- 区分通栏背景、版心内容、公共区域和重复模块
- 读取宽高、间距、字体、行高、颜色、边框、圆角和阴影
- 判断图片应作为内容图片还是 CSS 背景
- 识别导航、按钮和卡片的默认、悬停、选中等状态
- 在编码前画出页面结构草图
资源管理
- 从蓝湖导出合适格式和清晰度的图片、图标等资源
- 按图片、图标、字体等类型分类存放
- 使用表达用途的英文或拼音命名资源
- 避免重复资源、临时截图和无用文件进入最终目录
- 检查相对路径,保证移动整个项目后仍能正常运行
页面实现
- 使用合适的语义化标签组织 Header、导航、主体和 Footer
- 使用版心、标准流和 Flex 完成主要布局
- 仅在覆盖、角标和悬浮等场景中使用定位
- 提取公共颜色、字体、按钮、卡片和标题样式
- 控制图片比例、文字换行、内容溢出和固定区域尺寸
- 保持选择器范围清晰,避免页面样式互相污染
视觉检查与调试
- 在设计图对应的浏览器尺寸下对比页面
- 按整体布局、区域尺寸、间距、文字、颜色和装饰的顺序检查
- 使用 Elements、Styles 和 Computed 面板定位偏差来源
- 使用 Network 面板检查图片、字体和样式资源
- 建立问题清单,逐项记录、修复和复查
项目任务
- 设计分析:输出页面清单、设计标注表和结构草图。
- 资源整理:导出并分类存放全部项目资源。
- 项目初始化:建立 HTML、公共 CSS、页面 CSS 和资源目录。
- 公共区域:完成公共头部、导航和页脚。
- 主体区域:完成设计图要求的全部页面和内容模块。
- 状态样式:补充设计中存在的悬停、选中等状态。
- 视觉对比:输出设计图与实现页面的对比截图和问题清单。
- 最终整理:清除临时内容、无效样式和无用资源,提交完整目录。
本周产出
- 页面清单和结构草图
- 蓝湖关键标注记录
- 分类清晰的资源目录
- 纯静态官网完整源码
- 设计图与实现页面的对比截图
- 已关闭的视觉问题清单
验收标准
页面完整性
- 设计图要求的页面和区域全部完成
- 文案、图片、图标和链接无遗漏
- 直接打开入口 HTML 后能够正常访问页面
- 图片、字体和样式资源全部加载成功
视觉还原
- 在指定浏览器和设计尺寸下,整体布局与设计图一致
- 版心、主要区域尺寸和对齐方式符合蓝湖标注
- 字体、字号、行高、颜色、背景、边框和圆角符合标注
- 页面无明显错位、遮挡、溢出、图片拉伸或意外横向滚动
代码质量
- HTML 结构清晰,主要区域使用合适的语义化标签
- CSS 按公共样式和页面样式合理组织
- 重复样式得到复用,类名能够表达用途
- 未大量使用无意义的绝对定位完成主体布局
- 项目中没有调试代码、临时资源和无效文件
第 6 周:JavaScript 基础与控制台版 2048
本周目标
本周完成后,应能够:
- 使用变量、数据类型和运算符表达程序状态与计算过程
- 使用条件和循环解决基础流程问题
- 使用数组和对象组织一组数据
- 使用函数拆分逻辑并减少重复代码
- 使用常用字符串、数组、Math 和日期能力处理数据
- 阅读基础错误信息,并使用控制台和断点定位问题
- 综合使用数组、对象和纯函数完成可操作的控制台版 2048
学习资料
JavaScript 参考视频待定。当前按以下知识范围和练习任务执行,确定课程后再补充视频章节映射。
需要掌握的知识点
运行环境与语法基础
- JavaScript 在浏览器中的运行方式
- 内部脚本和外部脚本的引入方式
console.log()、浏览器控制台和基础断点- 语句、表达式、注释和代码块
let、const的使用场景和命名规范
数据类型与运算
- 字符串、数字、布尔值、
undefined和null typeof和基础类型判断- 显式与隐式类型转换
- 算术、赋值、比较和逻辑运算符
===与==的区别,默认使用严格相等- 模板字符串和字符串拼接
流程控制
if、else if、elseswitch的使用场景for、while循环break和continue- 循环边界、初始化条件和终止条件
- 使用流程图或伪代码描述复杂判断
数组
- 数组创建、索引、长度和遍历
- 数组元素的增加、删除和修改
push、pop、shift、unshift、splice- 查找、筛选、转换和汇总的基本思路
- 二维数组的结构和遍历
纯函数与二维数组处理
- 函数的结果只由参数决定,不依赖或修改外部状态
- 返回新数组,不直接修改传入的数组
- 使用嵌套循环遍历二维数组
- 比较两个二维数组的内容是否一致
- 将复杂规则拆分为多个可单独测试的小函数
函数
- 函数声明、函数表达式和箭头函数
- 参数、默认值、返回值和提前返回
- 局部作用域与外部变量
- 将复杂问题拆分为多个职责单一的函数
- 回调函数的基本概念
对象与常用能力
- 对象、属性、方法和遍历
- 数组与对象组合的数据结构
- 字符串常用方法
Math的随机数、取整和极值能力- 日期对象的基础使用
- 解构和展开语法
调试与代码质量
SyntaxError、ReferenceError、TypeError等基础错误- 使用日志缩小问题范围
- 使用断点观察变量和执行顺序
- 变量、函数命名和适当的函数长度
- 为练习准备输入、预期输出和实际输出
控制台输入与输出
- 使用
console.table()输出二维棋盘 - 使用
console.clear()清理上一轮输出 - 使用
prompt()接收玩家指令 - 对输入进行大小写转换和合法性检查
- 使用循环维持游戏流程,并提供明确的退出条件
必做练习
以下练习用于掌握 JavaScript 基础,同时为控制台版 2048 准备可复用函数。
- 方向指令判断:实现
isValidDirection(input),判断输入是否为W、A、S、D,不区分大小写。 - 创建空棋盘:实现
createEmptyBoard(size = 4),使用循环返回指定尺寸的二维数组,所有位置初始值为 0。 - 统计空位数量:实现
countEmptyCells(board),使用嵌套循环统计二维棋盘中 0 的数量。 - 查找最大数字:实现
getMaxTile(board),返回棋盘中的最大数字;空棋盘返回 0。 - 反转一行数字的位置:实现
reverseLine(line),将数组元素按照原位置从后往前重新排列。反转只改变元素顺序,不修改数字本身,也不是按数字大小排序。例如,输入[2, 0, 4, 8],输出[8, 4, 0, 2];输入[2, 2, 4, 0],输出[0, 4, 2, 2]。函数必须返回新数组,不能修改传入数组。 - 复制二维棋盘:实现
cloneBoard(board),修改返回的棋盘时不能影响原棋盘。 - 提取指定列:实现
getColumn(board, colIndex),把二维棋盘中的指定列提取为一维数组。 - 写回指定列:实现
setColumn(board, colIndex, column),把一维数组写入指定列,并返回新棋盘。 - 随机整数:实现
randomIndex(length),返回0到length - 1之间的随机整数;length不合法时返回明确结果。 - 记录测试结果:为以上每个函数至少准备一个正常用例和一个边界用例,记录输入、预期输出和实际输出。
这些练习分别对应后续综合任务中的输入校验、棋盘初始化、空位查找、左右移动、上下移动、状态复制和随机数字生成。
本周综合任务:控制台版 2048
使用原生 JavaScript 实现一个可以在浏览器控制台中运行的基础可玩版 2048。游戏使用 console.table() 显示棋盘,使用 prompt() 接收操作。
难度评估:中等,约为完整版本的 60%-70%。完成上述必做练习后,大部分辅助函数可以直接复用。应按以下任务顺序逐步实现,每完成一个函数先通过测试,再进入下一项任务。
输入约定:本综合任务按标准 2048 棋盘验收。line 参数为长度 4 的一维数组,元素为 0 或正整数;board 参数为 4×4 二维数组,每个格子为 0 或正整数;玩家指令为字符串或关闭输入框得到的 null。
任务一:压缩一行数字
实现 compactLine(line),将所有非零数字移动到左侧,并在右侧补零。
- 函数签名:
compactLine(line) - 输入:长度 4 的一维数组
line,表示棋盘中的一行,例如[2, 0, 2, 4] - 输出:新的同长度一维数组,非零数字保持原相对顺序并移动到左侧,例如
[2, 2, 4, 0] - 约束:返回新数组,保持传入的
line不变
查看提示
先使用 filter() 或循环取出所有非零数字,再根据缺少的数量补 0。复制数组后再处理,避免修改参数。
任务二:向左合并一行数字
实现 mergeLineLeft(line),返回合并后的数组。一次移动中,每个数字最多参与一次合并。
- 函数签名:
mergeLineLeft(line) - 输入:长度 4 的一维数组
line,表示移动前的一行数字 - 输出:新的同长度一维数组,表示向左移动并合并后的结果
- 示例:
[2, 2, 2, 2]返回[4, 4, 0, 0] - 示例:
[2, 2, 4, 0]返回[4, 4, 0, 0] - 示例:
[4, 0, 4, 4]返回[8, 4, 0, 0] - 示例:
[0, 0, 0, 0]返回[0, 0, 0, 0] - 约束:返回新数组,保持传入的
line不变
查看提示
先压缩,再从左向右扫描;发现相邻数字相同时合并,并让索引额外前进一步,避免同一个数字连续合并两次。
任务三:查找所有空位
实现 getEmptyCells(board),返回 4×4 棋盘中所有值为 0 的位置。每个位置使用 { row, col } 表示。
- 函数签名:
getEmptyCells(board) - 输入:4×4 二维数组
board,表示当前棋盘 - 输出:数组,每一项是一个空位坐标对象
{ row, col } - 示例:输入
[[2, 0, 0, 0], [0, 4, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]],输出包含{ row: 0, col: 1 }和{ row: 1, col: 0 }等空位 - 边界:没有空位时输出空数组
[]
查看提示
在必做练习 countEmptyCells() 的两层循环基础上,把“数量加一”改为将 { row, col } 加入结果数组。
任务四:比较两个棋盘
实现 boardsEqual(boardA, boardB),逐项比较两个二维数组。尺寸或任意数字不同都返回 false。
- 函数签名:
boardsEqual(boardA, boardB) - 输入:两个二维数组
boardA和boardB;主要用于比较两个 4×4 棋盘,也要能识别尺寸不同的情况 - 输出:布尔值;完全一致返回
true,否则返回false - 示例:
boardsEqual([[2, 0]], [[2, 0]])返回true - 示例:
boardsEqual([[2, 0]], [[0, 2]])返回false - 边界:行数不同、列数不同都返回
false
查看提示
先比较行数和每行长度,再逐项比较;发现不同后立即返回 false。
任务五:判断是否达到目标数字
实现 hasTarget(board, target = 2048),判断棋盘中是否存在目标数字。
- 函数签名:
hasTarget(board, target = 2048) - 输入:4×4 二维数组
board;可选正整数target,默认值为2048 - 输出:布尔值;棋盘中存在目标数字返回
true,否则返回false - 示例:
hasTarget([[2, 4, 8, 16], [32, 64, 128, 256], [512, 1024, 2048, 0], [0, 0, 0, 0]])返回true - 示例:
hasTarget([[2, 4, 8, 16], [32, 64, 128, 256], [512, 1024, 0, 0], [0, 0, 0, 0]], 2048)返回false
查看提示
可以使用两层循环,也可以组合 some();找到目标后不需要继续遍历。
任务六:判断是否还可以移动
实现 canMove(board)。满足以下任意条件时返回 true:
- 棋盘中仍有空位
- 水平方向存在相邻且相同的数字
- 垂直方向存在相邻且相同的数字
只需要向右和向下检查相邻位置,避免重复判断或数组越界。
- 函数签名:
canMove(board) - 输入:4×4 二维数组
board,表示当前棋盘 - 输出:布尔值;仍可移动返回
true,不能移动返回false - 示例:
canMove([[2, 0, 4, 8], [16, 32, 64, 128], [256, 512, 1024, 2], [4, 8, 16, 32]])返回true - 示例:
canMove([[2, 4, 2, 4], [4, 2, 4, 2], [2, 4, 2, 4], [4, 2, 4, 2]])返回false - 示例:
canMove([[2, 2, 4, 8], [16, 32, 64, 128], [256, 512, 1024, 2], [4, 8, 16, 32]])返回true
查看提示
先调用 getEmptyCells() 判断是否存在空位;没有空位时,只比较当前位置与右侧、下方的数字。
任务七:判断游戏是否失败
实现 isGameOver(board)。棋盘没有空位,并且水平方向、垂直方向都不存在可合并数字时,返回 true。
- 函数签名:
isGameOver(board) - 输入:4×4 二维数组
board,表示当前棋盘 - 输出:布尔值;游戏失败返回
true,否则返回false - 示例:
isGameOver([[2, 4, 2, 4], [4, 2, 4, 2], [2, 4, 2, 4], [4, 2, 4, 2]])返回true - 示例:
isGameOver([[2, 2, 4, 8], [16, 32, 64, 128], [256, 512, 1024, 2], [4, 8, 16, 32]])返回false - 示例:
isGameOver([[2, 0, 4, 8], [16, 32, 64, 128], [256, 512, 1024, 2], [4, 8, 16, 32]])返回false
查看提示
不要重复编写判断规则,可以直接复用 canMove() 并对结果取反。
任务八:实现四个方向移动
在 mergeLineLeft() 的基础上实现 moveLeft()、moveRight()、moveUp() 和 moveDown()。每次移动返回新棋盘及棋盘是否变化。
- 函数签名:
moveLeft(board)、moveRight(board)、moveUp(board)、moveDown(board) - 输入:4×4 二维数组
board,表示移动前的棋盘 - 输出:对象
{ board: newBoard, changed } - 输出说明:
newBoard是移动后的新棋盘;changed是布尔值,表示棋盘是否发生变化 - 示例:
moveLeft([[2, 0, 2, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]])输出{ board: [[4, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], changed: true } - 示例:
moveLeft([[2, 4, 8, 16], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]])输出changed: false - 约束:返回新棋盘,保持传入的
board不变
查看提示
复用必做练习中的 reverseLine()、getColumn() 和 setColumn()。向右移动可以先反转每一行,左移后再反转;上下移动可以先提取一列,按一行处理后再写回新棋盘。先完成左右,再处理上下。
任务九:生成随机数字
实现 addRandomTile(board),随机选择一个空位并生成数字 2。
- 函数签名:
addRandomTile(board) - 输入:4×4 二维数组
board,表示生成新数字前的棋盘 - 输出:新的二维数组,在一个随机空位上写入数字
2 - 示例:输入一个全 0 的 4×4 棋盘,输出棋盘中应只有一个位置是
2,其他位置仍是0 - 边界:如果没有空位,返回与输入内容一致的新棋盘
- 约束:返回新棋盘,保持传入的
board不变
查看提示
复用 getEmptyCells()、randomIndex() 和 cloneBoard(),先选择随机空位并复制棋盘,再写入数字。
任务十:初始化游戏
创建 4×4 空棋盘,并随机生成两个初始数字。
- 函数签名:
initGame() - 输入:无
- 输出:4×4 二维数组,包含两个随机生成的数字
2 - 示例:输出棋盘中应有 2 个非零格子,并且这 2 个格子的值都为
2 - 约束:两个初始数字不能出现在同一个格子
查看提示
复用必做练习中的 createEmptyBoard(),再连续调用两次 addRandomTile() 生成初始棋盘。
任务十一:实现控制台游戏循环
使用循环输出棋盘和操作提示,并通过 prompt() 接收指令:W 上、A 左、S 下、D 右。指令不区分大小写。
- 函数建议:
startGame() - 输入:玩家通过
prompt()输入的字符串,例如W、A、S、D;关闭输入框时输入值为null - 输出:通过
console.table()输出当前棋盘;通过alert()或console.log()输出无效输入、胜利或失败提示 - 流程输出:每次有效移动后展示更新后的棋盘
- 边界:无效指令保持棋盘不变;无效移动保持棋盘不变;关闭输入框时结束脚本
查看提示
先将输入统一转换为大写,再使用对象映射或 switch 选择移动函数。根据移动结果中的 changed 判断是否生成新数字;关闭输入框时可以结束脚本。
任务十二:完成胜负流程
出现 2048 时提示胜利;棋盘无法继续移动时提示失败,随后结束游戏循环。
- 函数建议:在
startGame()中调用hasTarget()和isGameOver() - 输入:每次有效移动并生成新数字后的棋盘
- 输出:胜利时输出明确胜利提示并结束循环;失败时输出明确失败提示并结束循环
- 示例:棋盘中出现
2048时,输出你赢了 - 示例:
isGameOver(board)为true时,输出游戏结束 - 约束:胜负判断应发生在棋盘状态更新之后
查看提示
一次有效移动的顺序应为“移动 -> 判断棋盘变化 -> 生成数字 2 -> 检查胜负 -> 输出新棋盘”。
实现要求
- 每个函数只负责一个明确任务
- 使用控制台完成输入输出
- 通过函数参数和返回值传递游戏状态
- 不直接修改传入的数组或棋盘
- 核心函数至少包含一个正常用例和一个边界用例
- 游戏逻辑与控制台输入输出分开组织
- 游戏代码放入
console-2048.js - 核心逻辑测试放入
console-2048.test.js或独立测试区域
本周产出
- 2048 JavaScript 基础练习及测试记录
- 可实际游玩的控制台版 2048
- 2048 核心逻辑测试记录
- 一份错误与调试记录
- 一份 JavaScript 与 C 语言差异笔记
完成检查
-
能够区分
let和const - 能够正确使用条件、循环和函数
- 能够选择数组或对象组织数据
- 能够把长逻辑拆成多个职责清晰的函数
- 能够使用控制台和断点定位基础错误
- 已完成可实际游玩的控制台版 2048
- 支持四向移动、固定生成数字 2 及胜负判断
- 无效输入和无效移动不会改变棋盘
- 核心逻辑未直接修改输入数据
- 每个 2048 核心函数均具有可重复执行的测试用例
第 7 周:DOM、Git 与 2048 网页化
本周目标
本周完成后,应能够:
- 使用 DOM 查询、修改、创建和删除页面元素
- 使用事件监听实现点击和键盘交互
- 解释事件对象、事件冒泡和阻止默认行为
- 使用 Git 完成暂存、提交、查看历史和推送
- 将第 6 周的控制台版 2048 迁移为网页界面
- 将游戏数据、移动逻辑和页面渲染分离
- 复用已完成的四向移动、合并和状态判断逻辑,并补充计分与重新开始
学习资料
JavaScript 参考视频待定。DOM 相关视频范围将在课程确定后补充;Git 使用基础命令完成本周项目管理。
需要掌握的知识点
DOM 操作
- DOM 树及 HTML 与节点的关系
querySelector、querySelectorAll- 文本内容、HTML 内容和表单值
- 元素属性、自定义属性、样式和
classList - 创建、追加、插入和删除节点
- 遍历节点集合并批量更新页面
事件
addEventListener和事件处理函数- 点击、输入和键盘事件
- 事件对象及按键判断
- 事件冒泡和事件委托的基本概念
- 阻止默认行为
- 避免重复绑定事件
Git 与 GitHub
- 仓库、工作区、暂存区和提交历史
git init、git status、git add、git commit、git log.gitignore的用途- 创建 GitHub 仓库、关联远程仓库和推送代码
- 使用清晰提交信息描述已完成的功能
- 每完成一个独立功能进行一次提交
2048 状态建模
- 复用第 6 周控制台版的 4×4 棋盘和初始化逻辑
- 根据棋盘数据渲染 DOM
- 页面只负责显示,JavaScript 数据作为游戏状态来源
- 复用第 6 周的棋盘比较函数,判断移动是否有效
移动与合并算法
- 复用第 6 周的
compactLine()和mergeLineLeft() - 扩展单行合并结果,将合并产生的数字计入当前分数
- 使用反转、行列转换等方法处理不同移动方向
- 将单行算法扩展到左、右、上、下四个方向
随机数字生成
- 复用第 6 周的空位查找和随机数字函数
- 在固定生成数字 2 的基础上,增加小概率生成数字 4
- 仅在棋盘发生有效变化后生成新数字
- 棋盘无空位时不执行生成操作
必做练习
- 实现点击切换内容的标签页。
- 实现支持添加、完成和删除的待办事项列表。
- 实现方向键控制页面方块移动。
- 创建 2048 Git 仓库和 GitHub 远程仓库。
- 将第 6 周的棋盘状态接入数据驱动的 DOM 渲染。
- 复用控制台版的移动、合并和胜负判断函数,并增加计分。
- 使用键盘事件替换
prompt()指令输入。 - 增加重新开始按钮及游戏状态重置。
- 增加小概率生成数字 4,并保证核心合并规则不变。
核心规则测试
[2, 2, 2, 2]左移得到[4, 4, 0, 0][2, 2, 4, 0]左移得到[4, 4, 0, 0][4, 0, 4, 4]左移得到[8, 4, 0, 0][0, 0, 0, 0]左移后保持不变- 只有位置变化但没有合并时,分数不增加
- 棋盘没有变化时,不生成新数字
Git 提交要求
本周至少通过独立提交体现以下开发步骤:
- 初始化项目结构和页面
- 完成棋盘数据与渲染
- 迁移第 6 周控制台版核心逻辑
- 完成 DOM 棋盘渲染
- 使用键盘事件完成四向控制
- 完成计分、重新开始和数字 4 的随机生成
本周产出
- 标签页与待办事项 DOM 练习
- 2048 GitHub 仓库
- 可以操作的 2048 网页游戏主体
- 核心移动规则测试记录
- 一份游戏输入、状态更新和页面渲染流程图
完成检查
- 能够使用 DOM 和事件实现基础交互
- 棋盘数据与页面展示保持一致
- 四个方向均可正常移动和合并
- 一次移动中每个方块最多参与一次合并
- 无效移动不会生成新数字
- 能够正确计分并通过按钮重新开始
- Git 提交能够体现主要功能的开发过程
- 2048 已推送至 GitHub
第 8 周:2048 蓝湖设计图还原与验收
本周目标
本周完成后,应能够:
- 使用第 7 周完成的计分与重新开始功能,完成完整游戏流程
- 使用本地存储保存并恢复最高分
- 根据提供的 2048 蓝湖设计图完成游戏界面还原
- 编写稳定、不因数字和状态变化而错位的游戏界面
- 为核心规则设计并执行明确的测试用例
- 根据测试结果定位并修复逻辑问题
- 整理代码结构、Git 提交和 GitHub 项目说明
- 独立讲解 2048 的状态、移动算法和渲染流程
需要掌握的知识点
蓝湖设计图分析
- 确认设计图对应的页面尺寸和目标浏览器宽度
- 读取棋盘、方块、间距、圆角、颜色、字体和阴影标注
- 导出设计图中的图片、图标和字体等资源
- 划分标题区、分数区、操作区、棋盘和状态提示区域
- 识别默认、胜利、失败和重新开始等界面状态
- 使用对比截图记录并修复视觉偏差
分数与状态
- 仅在数字合并时增加当前分数
- 每次合并增加新方块对应的数值
- 区分进行中、胜利和失败状态
- 复用第 6 周的
hasTarget()进行胜利判断 - 复用第 6 周的
isGameOver()进行失败判断 - 避免游戏结束后继续修改状态
游戏生命周期
- 初始化棋盘和两个随机数字
- 处理一次用户输入和完整状态更新
- 重新开始时清空棋盘、当前分数和提示状态
- 在合适时机保留或更新最高分
- 处理连续点击重新开始等重复操作
本地存储
localStorage的读取、写入和删除- 字符串与数字之间的转换
- 首次访问时不存在存储值的处理
- 存储值异常时使用合理默认值
- 刷新页面后恢复最高分
界面稳定性
- 棋盘和方块尺寸、间距、颜色及圆角符合蓝湖标注
- 不同数字的字体和背景色符合蓝湖设计
- 当前分数、最高分、状态提示和按钮布局符合设计图
- 文本不会遮挡棋盘或操作区域
- 在设计图对应尺寸下无明显错位或溢出
- 控制台无错误,图片和样式资源无加载失败
测试与调试
- 为移动函数准备确定的棋盘输入和预期输出
- 分别测试正常情况、边界情况和无效操作
- 记录实际结果与预期结果的差异
- 修复问题后重新执行全部规则测试
- 临时测试入口在最终提交前移除
代码与项目整理
- 将状态、移动、渲染、输入和存储逻辑合理拆分
- 函数和变量名称能够表达实际用途
- 删除调试日志、重复代码和无用资源
- README 包含项目介绍、功能、运行方式、操作方法和截图
- 最终代码推送至 GitHub
必做任务
- 分析 2048 蓝湖设计图,整理页面结构、关键标注和资源清单。
- 根据设计图调整第 7 周完成的 HTML 结构和页面区域。
- 根据蓝湖标注完成标题、分数区、操作区、棋盘、方块、提示和按钮样式。
- 检查并完善当前分数、最高分、胜利、失败、重新开始和状态提示。
- 使用
localStorage保存并恢复最高分。 - 在设计图对应尺寸下截图对比,并逐项修复视觉偏差。
- 执行全部规则测试并记录结果。
- 整理核心函数、命名、目录和静态资源。
- 编写项目 README 并推送最终代码。
- 准备一次 5 分钟项目讲解。
功能验收
- 使用 HTML、CSS 和原生 JavaScript 开发,未使用游戏框架
- 使用 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 文件职责清晰
- 核心移动和合并逻辑已拆分为独立函数
- 页面无明显错位、遮挡或控制台报错
- 能够独立讲解棋盘状态、移动合并算法和渲染流程
视觉验收
- 页面结构和区域顺序与 2048 蓝湖设计图一致
- 棋盘、方块、间距、圆角和阴影符合蓝湖标注
- 字体、字号、文字颜色和背景颜色符合设计图
- 分数、按钮和状态提示在内容变化时不会引起布局跳动
- 页面无明显错位、遮挡、溢出或资源加载失败
- 已提供设计图与最终页面的对比截图
本周产出
- 2048 最终验收版本
- 完整的规则测试记录
- 蓝湖设计图标注记录和视觉对比截图
- 包含说明和截图的 GitHub 仓库
- 一份阶段一知识复盘和待补强清单
- 两个阶段项目的口头讲解提纲
graph LR
%% ===== 根节点 =====
HTML["HTML 知识树"]
%% ===== 一级分支 =====
HTML --> Basic["① 文档基础"]
HTML --> Text["② 文本与内容语义"]
HTML --> Link["③ 链接与导航"]
HTML --> Image["④ 图片与图形"]
HTML --> Data["⑤ 列表与表格"]
HTML --> Form["⑥ 表单"]
HTML --> Semantic["⑦ 语义化布局"]
HTML --> Media["⑧ 多媒体与嵌入内容"]
HTML --> Metadata["⑨ head 与元数据"]
HTML --> A11y["⑩ 可访问性"]
HTML --> Quality["⑪ 规范、调试与质量"]
%% ===== ① 文档基础 =====
Basic --> Skeleton["HTML 文档骨架"]
Basic --> Syntax["标签、元素与属性"]
Basic --> Nesting["嵌套与父子关系"]
Basic --> Void["空元素"]
Basic --> Comment["注释"]
Basic --> GlobalAttr["全局属性"]
Basic --> Path["资源路径"]
Basic --> Entity["字符实体"]
Skeleton --> Doctype["<!DOCTYPE html>"]
Skeleton --> HtmlTag["html / head / body"]
Syntax --> StartEnd["开始标签 / 结束标签"]
Syntax --> AttrValue["属性名 / 属性值"]
Void --> VoidTags["img / input / br / hr / meta / link"]
GlobalAttr --> IdClass["id / class"]
GlobalAttr --> TitleAttr["title / hidden"]
GlobalAttr --> DataAttr["data-* 自定义数据"]
Path --> AbsolutePath["绝对 URL"]
Path --> RelativePath["相对路径 ./ ../"]
Entity --> CommonEntity["< / > / & / "]
%% ===== ② 文本与内容语义 =====
Text --> Heading["标题层级 h1-h6"]
Text --> Paragraph["段落与分隔"]
Text --> Emphasis["强调与重要性"]
Text --> Edit["编辑标记"]
Text --> CodeText["代码与预格式文本"]
Text --> Quote["引用"]
Text --> Meaning["时间、缩写与联系信息"]
Text --> Generic["无特定语义容器"]
Paragraph --> PTag["p"]
Paragraph --> BrHr["br / hr"]
Emphasis --> StrongEm["strong / em"]
Emphasis --> BI["b / i / mark / small"]
Edit --> DelIns["del / ins"]
CodeText --> CodePre["code / pre / kbd / samp"]
Quote --> BlockInlineQuote["blockquote / q / cite"]
Meaning --> TimeAbbr["time / abbr / address"]
Generic --> DivSpan["div / span"]
%% ===== ③ 链接与导航 =====
Link --> Anchor["a 与 href"]
Link --> LinkPath["链接地址"]
Link --> Fragment["页内锚点 #id"]
Link --> NewWindow["新窗口与安全"]
Link --> Protocol["特殊协议"]
Link --> Download["下载链接"]
Link --> NavTag["nav 导航区域"]
LinkPath --> ExternalLink["外部链接"]
LinkPath --> InternalLink["站内相对链接"]
NewWindow --> TargetBlank["target=_blank"]
NewWindow --> RelNoopener["rel=noopener noreferrer"]
Protocol --> MailTel["mailto: / tel:"]
%% ===== ④ 图片与图形 =====
Image --> Img["img"]
Image --> Alt["替代文本 alt"]
Image --> ImgSize["width / height"]
Image --> Lazy["loading=lazy"]
Image --> Figure["figure / figcaption"]
Image --> ResponsiveImage["响应式图片"]
Image --> SVG["SVG"]
Image --> Canvas["canvas"]
Img --> Src["src"]
ResponsiveImage --> SrcsetSizes["srcset / sizes"]
ResponsiveImage --> PictureSource["picture / source"]
SVG --> SvgUse["矢量图形 / 图标"]
Canvas --> CanvasUse["像素画布 / 脚本绘制"]
%% ===== ⑤ 列表与表格 =====
Data --> List["列表"]
Data --> Table["表格"]
List --> Unordered["ul / li"]
List --> Ordered["ol / li"]
List --> Description["dl / dt / dd"]
Table --> TableBase["table / tr / th / td"]
Table --> TableGroup["thead / tbody / tfoot"]
Table --> Caption["caption"]
Table --> HeaderScope["表头与 scope"]
Table --> MergeCell["colspan / rowspan"]
%% ===== ⑥ 表单 =====
Form --> FormTag["form"]
Form --> Label["label 与控件关联"]
Form --> Input["input"]
Form --> Choice["选择类控件"]
Form --> Textarea["textarea"]
Form --> Select["select / option / optgroup"]
Form --> Button["button"]
Form --> Group["fieldset / legend"]
Form --> Validation["原生表单校验"]
Form --> State["控件状态"]
Form --> Autofill["自动填充"]
FormTag --> SubmitTarget["action / method"]
FormTag --> Encode["enctype"]
Input --> InputType["text / password / email / number / date / file"]
Input --> NameValue["name / value"]
Input --> Placeholder["placeholder"]
Choice --> Radio["radio"]
Choice --> Checkbox["checkbox"]
Button --> ButtonType["submit / button / reset"]
Validation --> Required["required"]
Validation --> Pattern["pattern / min / max / minlength / maxlength"]
State --> DisabledReadonly["disabled / readonly"]
Autofill --> Autocomplete["autocomplete"]
%% ===== ⑦ 语义化布局 =====
Semantic --> Header["header"]
Semantic --> Nav["nav"]
Semantic --> Main["main"]
Semantic --> Section["section"]
Semantic --> Article["article"]
Semantic --> Aside["aside"]
Semantic --> Footer["footer"]
Semantic --> HeadingOutline["标题层级"]
Semantic --> SemanticVsDiv["语义元素 vs div"]
%% ===== ⑧ 多媒体与嵌入内容 =====
Media --> Audio["audio"]
Media --> Video["video"]
Media --> Source["source 多格式资源"]
Media --> Track["track 字幕"]
Media --> Iframe["iframe"]
Media --> EmbedLegacy["embed / object"]
Audio --> MediaControls["controls / autoplay / loop / muted"]
Video --> VideoAttr["poster / width / height"]
Track --> CaptionTrack["captions / subtitles"]
Iframe --> IframeTitle["title"]
Iframe --> IframeSafe["sandbox / allow"]
Iframe --> IframeLazy["loading=lazy"]
%% ===== ⑨ head 与元数据 =====
Metadata --> Charset["meta charset"]
Metadata --> Viewport["meta viewport"]
Metadata --> Title["title"]
Metadata --> DescriptionMeta["meta description"]
Metadata --> Language["html lang"]
Metadata --> LinkTag["link"]
Metadata --> StyleTag["style"]
Metadata --> ScriptTag["script"]
Metadata --> SocialMeta["社交分享元数据"]
Metadata --> RobotMeta["robots"]
LinkTag --> Stylesheet["stylesheet"]
LinkTag --> Favicon["favicon"]
LinkTag --> ResourceHint["preload / preconnect"]
ScriptTag --> ScriptLoad["defer / async"]
SocialMeta --> OpenGraph["Open Graph"]
%% ===== ⑩ 可访问性 =====
A11y --> NativeSemantic["优先使用原生语义"]
A11y --> AccessibleName["可访问名称"]
A11y --> Keyboard["键盘操作"]
A11y --> Focus["焦点顺序"]
A11y --> ImageA11y["图片替代文本"]
A11y --> FormA11y["表单标签与错误提示"]
A11y --> TableA11y["表格标题与表头"]
A11y --> MediaA11y["字幕与文字稿"]
A11y --> ARIA["ARIA"]
AccessibleName --> NameSource["文字 / label / alt / aria-label"]
Keyboard --> NativeControl["button / a / input"]
Focus --> Tabindex["tabindex"]
ARIA --> AriaRule["无 ARIA 胜过错误 ARIA"]
ARIA --> AriaState["aria-expanded / aria-current / aria-live"]
%% ===== ⑪ 规范、调试与质量 =====
Quality --> DOM["DOM 树"]
Quality --> DevTools["浏览器开发者工具"]
Quality --> Validator["HTML 校验"]
Quality --> Formatting["缩进与可读性"]
Quality --> Deprecated["废弃与表现型标签"]
Quality --> Compatibility["浏览器兼容与渐进增强"]
Quality --> SEO["基础 SEO"]
Quality --> Performance["资源与加载性能"]
Quality --> Security["基础安全意识"]
DevTools --> ElementsPanel["Elements / Accessibility"]
Validator --> W3CValidator["标签嵌套 / 属性错误"]
Deprecated --> OldTags["font / center / marquee"]
SEO --> SeoBasic["语义 / title / description / heading"]
Performance --> ImgPerformance["图片尺寸 / 懒加载"]
Performance --> LoadOrder["CSS / JavaScript 加载"]
Security --> ExternalSafe["外部链接安全"]
Security --> IframeSecurity["iframe 限权"]
Security --> UserContent["不信任用户输入"]
%% ===== 学习优先级 =====
classDef root fill:#6366f1,stroke:#4338ca,color:#fff,stroke-width:3px
classDef level1 fill:#3b82f6,stroke:#2563eb,color:#fff,stroke-width:2px
classDef must fill:#16a34a,stroke:#15803d,color:#fff
classDef know fill:#f59e0b,stroke:#d97706,color:#fff
class HTML root
class Basic,Text,Link,Image,Data,Form,Semantic,Media,Metadata,A11y,Quality level1
class Skeleton,Heading,Paragraph,Anchor,Img,Alt,List,TableBase,FormTag,Label,Input,Button,Header,Nav,Main,Section,Article,Footer,Charset,Viewport,Title,Language,NativeSemantic,DevTools must
class ResponsiveImage,SVG,Canvas,Validation,Iframe,SocialMeta,ARIA,Validator,SEO,Performance,Security know
graph LR
%% ===== 根节点 =====
CSS["🎨 CSS 知识树"]
%% ===== 一级分支 =====
CSS --> Basic["① 基础语法"]
CSS --> Box["② 盒模型"]
CSS --> Layout["③ 布局"]
CSS --> Visual["④ 视觉样式"]
CSS --> Typo["⑤ 文字排版"]
CSS --> Anim["⑥ 动画与过渡"]
CSS --> Responsive["⑦ 响应式设计"]
CSS --> Modern["⑧ 现代CSS特性"]
CSS --> Advanced["⑨ 高级概念"]
CSS --> Practice["⑩ 最佳实践"]
CSS --> Tools["⑪ 调试与工具"]
%% ===== ① 基础语法 =====
Basic --> Sel["选择器"]
Basic --> Cascade["层叠与优先级"]
Basic --> Units["单位"]
Sel --> SelBasic["元素/类/ID/通配符"]
Sel --> SelAttr["属性选择器"]
Sel --> SelCombo["组合选择器"]
Sel --> SelPseudo["伪类 & 伪元素 :hover ::before"]
Sel --> SelStruct["结构伪类 :nth-child :not"]
Cascade --> Inherit["继承 inherit/initial"]
Cascade --> Specificity["优先级计算"]
Cascade --> Important["!important"]
Units --> Abs["绝对 px/pt/cm"]
Units --> RelFont["相对 em/rem"]
Units --> Viewport["视口 vw/vh/vmin"]
%% ===== ② 盒模型 =====
Box --> Content["content"]
Box --> Padding["padding"]
Box --> Border["border"]
Box --> Margin["margin"]
Box --> Sizing["box-sizing"]
Border --> BorderRadius["border-radius"]
Border --> BorderImg["border-image"]
Margin --> MarginCollapse["margin 折叠"]
Margin --> NegMargin["负 margin"]
Sizing --> ContentBox["content-box"]
Sizing --> BorderBox["border-box ★"]
%% ===== ③ 布局 =====
Layout --> Display["display"]
Layout --> Float["float"]
Layout --> Position["position"]
Layout --> Flex["Flexbox ★"]
Layout --> Grid["Grid ★★"]
Layout --> MultiCol["多列布局"]
Display --> Block["block / inline"]
Display --> InlineBlock["inline-block"]
Display --> None["none / contents"]
Float --> FloatLR["left / right"]
Float --> Clearfix["clearfix"]
Float --> BFC["BFC 触发"]
Position --> Static["static"]
Position --> Relative["relative"]
Position --> Absolute["absolute"]
Position --> Fixed["fixed"]
Position --> Sticky["sticky"]
Flex --> FlexContainer["容器: justify-content / align-items"]
Flex --> FlexItem["项目: flex-grow / shrink / basis"]
Flex --> FlexDir["flex-direction / wrap"]
Grid --> GridContainer["容器: grid-template / gap"]
Grid --> GridItem["项目: grid-column / area"]
Grid --> GridArea["grid-template-areas"]
%% ===== ④ 视觉样式 =====
Visual --> Color["颜色"]
Visual --> Background["背景"]
Visual --> Gradient["渐变"]
Visual --> Shadow["阴影"]
Visual --> Filter["滤镜 filter"]
Visual --> Blend["混合模式"]
Visual --> Clip["裁剪 clip-path"]
Color --> Hex["十六进制 #fff"]
Color --> RGB["rgb / rgba"]
Color --> HSL["hsl / hsla"]
Color --> CurrentColor["currentColor"]
Background --> BgImg["background-image"]
Background --> BgSize["background-size"]
Background --> BgMulti["多重背景"]
Gradient --> Linear["linear-gradient"]
Gradient --> Radial["radial-gradient"]
Gradient --> Conic["conic-gradient"]
Shadow --> BoxShadow["box-shadow"]
Shadow --> TextShadow["text-shadow"]
Blend --> MixBlend["mix-blend-mode"]
Blend --> BgBlend["background-blend-mode"]
%% ===== ⑤ 文字排版 =====
Typo --> FontFamily["font-family"]
Typo --> FontSize["font-size / weight"]
Typo --> LineHeight["line-height"]
Typo --> TextAlign["text-align"]
Typo --> Decoration["text-decoration"]
Typo --> Spacing["letter / word-spacing"]
Typo --> Overflow["text-overflow ellipsis"]
Typo --> FontFace["@font-face"]
Typo --> WhiteSpace["white-space nowrap"]
%% ===== ⑥ 动画与过渡 =====
Anim --> Transition["transition"]
Anim --> Keyframes["@keyframes"]
Anim --> Animation["animation"]
Anim --> Transform["transform"]
Transition --> TransProp["transition-property"]
Transition --> TransTime["timing-function cubic-bezier"]
Transition --> TransDur["duration / delay"]
Keyframes --> KeyframeRule["@keyframes name"]
Keyframes --> KeyframePct["0% / 50% / 100%"]
Animation --> AnimName["animation-name"]
Animation --> AnimIter["iteration-count"]
Animation --> AnimDir["direction / fill-mode"]
Transform --> Translate["translate / rotate"]
Transform --> Scale["scale / skew"]
Transform --> Transform3D["3D transform perspective / translateZ"]
%% ===== ⑦ 响应式设计 =====
Responsive --> ViewportMeta["viewport meta"]
Responsive --> MediaQuery["@media 媒体查询"]
Responsive --> MobileFirst["移动优先策略"]
Responsive --> ResponsiveImg["响应式图片"]
MediaQuery --> MQWidth["min / max-width"]
MediaQuery --> MQRatio["aspect-ratio"]
MediaQuery --> MQOrient["orientation"]
MediaQuery --> MQHover["hover / pointer"]
ResponsiveImg --> Srcset["srcset / sizes"]
ResponsiveImg --> Picture["picture 元素"]
%% ===== ⑧ 现代CSS特性 =====
Modern --> CSSVar["自定义属性 --var / var()"]
Modern --> Supports["@supports 特性查询"]
Modern --> Calc["calc()"]
Modern --> MinMaxClamp["min / max / clamp()"]
Modern --> AspectRatio["aspect-ratio"]
Modern --> ContainerQuery["@container 容器查询"]
Modern --> HasSel[":has() 父选择器"]
Modern --> CascadeLayer["@layer 层叠层"]
Modern --> ColorMix["color-mix / contrast"]
%% ===== ⑨ 高级概念 =====
Advanced --> BFCConcept["BFC 块级格式上下文"]
Advanced --> IFCConcept["IFC 行内格式"]
Advanced --> Stacking["层叠上下文 z-index"]
Advanced --> ContainBlock["包含块"]
Advanced --> Reflow["重绘与回流"]
Advanced --> FormatModel["视觉格式化模型"]
%% ===== ⑩ 最佳实践 =====
Practice --> BEM["BEM 命名规范"]
Practice --> OOCSS["OOCSS / SMACSS"]
Practice --> CSSMod["CSS Modules"]
Practice --> CSSinJS["CSS-in-JS"]
Practice --> Utility["Tailwind / Utility-first"]
Practice --> Reset["reset / normalize"]
Practice --> Prefix["浏览器前缀"]
Practice --> Perf["性能优化"]
Perf --> CritCSS["关键CSS内联"]
Perf --> NoImport["避免 @import"]
Perf --> WillChange["will-change"]
%% ===== ⑪ 调试与工具 =====
Tools --> DevTools["浏览器 DevTools"]
Tools --> PostCSS["PostCSS"]
Tools --> AutoPrefix["Autoprefixer"]
Tools --> PreProc["预处理器"]
Tools --> Lint["Stylelint"]
PreProc --> Sass["Sass / SCSS"]
PreProc --> Less["Less"]
PreProc --> Stylus["Stylus"]
%% ===== 样式高亮 =====
classDef root fill:#6366f1,stroke:#4338ca,color:#fff,stroke-width:3px
classDef level1 fill:#3b82f6,stroke:#2563eb,color:#fff,stroke-width:2px
classDef hot fill:#f59e0b,stroke:#d97706,color:#fff
class CSS root
class Basic,Box,Layout,Visual,Typo,Anim,Responsive,Modern,Advanced,Practice,Tools level1
class Flex,Grid,ContainerQuery,HasSel,CSSVar hot
阶段二:Java 基础
详细计划待补充。
阶段三:前端工程化
详细计划待补充。
阶段四:后端进阶与全栈整合
详细计划待补充。
阶段五:AI Agent 提效
详细计划待补充。