目录
欢迎来到《Cocos 游戏开发入门》。这一卷要陪你做一件看起来有点「绕远」的事:先不用引擎,从零手写一个能跑的 2D 运行时 mini2d,再用 Cocos Creator 3.8 把同一款游戏做一遍。
绕远,是因为引擎把太多东西藏起来了。你在 Cocos 里拖一个节点、挂一个 Sprite、点一下运行,屏幕上就出现了图;但「一帧是怎么开始的、坐标是怎么换算的、纹理是怎么合批的、碰撞是怎么被检测到的」这些问题的答案,被封装进了你从未打开过的源码里。把同一件事先自己写一遍,再回头看引擎,你得到的不是「会用某个 API」,而是能判断引擎在某处为什么这样设计、以及它什么时候会成为瓶颈。
本页给出全书的阅读路线。你可以从第 1 章 1.1 开始顺序通读,也可以先看下面的三条路径,挑一条最合你胃口的走法。
这一卷写给谁
| 读者 | 现状 | 读完能拿到什么 |
|---|---|---|
| 有编程基础、想入行游戏客户端 | 会写业务代码,没碰过游戏循环与渲染 | 一套从零写出的 2D 运行时,和对照它的 Cocos 工程认知 |
| 用过 Unity / Godot,想转 Cocos | 熟悉引擎思维,但不清楚 Cocos 的机制边界 | Cocos Creator 3.8 的组件体系、资源管线与多端发布路径 |
| 前端 / Web 开发者 | 熟 Canvas 与 TypeScript,缺游戏工程经验 | 帧循环、输入手感、资源与存档、多端打包的完整实践 |
| 想自研小引擎或做小游戏 | 有想法,但被「从哪下手」卡住 | 一条可复制的实现路径:先最小可跑,再逐章长大 |
前置知识:会写 TypeScript(或 JavaScript),了解基本的面向对象与异步(Promise);数学只需高中水平——向量、矩阵、一点点三角函数。不需要图形学基础,也不需要装 Cocos Creator 编辑器才能读前 17 章。
三条阅读路径
路径 A:从零手写引擎(约 10 周)
最完整的一条,也最费时间。按顺序走完 18 章,每章的代码都亲手敲一遍。
第 1–3 章(地基)→ 第 4–6 章(时间/输入/对象)→ 第 7–11 章(表现)
→ 第 12–14 章(系统与玩法)→ 第 15–18 章(质量与交付)
适合想真正吃透 2D 引擎机制、或打算自研小引擎的读者。每章末节的「Cocos 对照」不要跳过——它把「你刚写的这段」和「引擎里的哪个模块」对上号。
路径 B:只学 Cocos,把 mini2d 当注解(约 6 周)
时间紧、目标是尽快上手 Cocos Creator 的话,可以只读每章的末节(Cocos 对照节),把前两节的 mini2d 实现当作「引擎为什么这样设计」的注解,遇到想深挖的点再回头补。
1.3 → 2.3 → 3.3 → 4.3 → 5.3 → 6.3 → 7.3 → 8.3
→ 9.3 → 10.3 → 11.3 → 12.3 → 13.3 → 14.3 → 15.3 → 16.3 → 17.3 → 18.1
这条路径读得快,但会牺牲一部分「知其所以然」。建议至少把第 4 章(时间与更新)和第 7 章(物理与碰撞)完整读——这两处最容易在引擎里「用错了也不知道」。
路径 C:按问题查(随时)
不打算通读,只在遇到具体问题时翻对应章节。下节「常见问题速查」就是为这条路准备的。
贯穿项目:《方块冲刺》
全书只有一个项目:《方块冲刺》——一款 2D 横版跑酷小游戏。玩家操控一个方块向右冲刺,跳过障碍、吃金币、捡道具,跑得越远分越高。
选它,是因为它体量小到能从零写完,又覆盖了 2D 游戏的全部关键面:
| 玩法要素 | 牵出的技术点 | 对应章节 |
|---|---|---|
| 方块跑跳 | 帧循环、固定步长、输入手感 | 1、4、5 |
| 障碍与金币 | 碰撞检测、宽相、触发器 | 7 |
| 关卡随距离推进 | 数据驱动、程序化生成 | 6、13 |
| 金币与道具 | 数值、掉落、经济 | 14 |
| 得分与结算 | 结算管线、UI 与存档 | 11、12、14 |
| 多端发布 | 构建、分包、平台适配 | 17 |
在卷一里,它会在 mini2d 上逐章长大:第 1 章还是一个只会动的小方块,到第 18 章已经是一个能打包、能多端发布、带测试的完整小游戏。卷二会换用 Cocos Creator 3.8 把同一款游戏重做一遍,卷三讲引擎内部,卷四给它加联机。
三层可运行性口径(重要)
这套书的示例分三层,每一层的可验证程度不同,读之前务必搞清楚,否则会误以为「所有代码都能一键跑起来」:
| 层 | 内容 | 能否真跑 | 怎么验证 |
|---|---|---|---|
| L1 | mini2d 从零实现(纯 TypeScript,零 cc 依赖) | 能真跑 | Node + vitest 单测、Playwright 无头截图 |
| L2 | Cocos 组件脚本(import { X } from 'cc') | 能真做类型检查 | tsc --noEmit 对 @cocos/creator-types@3.8.8 检查 |
| L3 | Cocos 工程文件(.scene / .prefab / .meta) | 不能命令行复现 | 结构校验;正文会显式标注「需编辑器」 |
为什么这样分? 因为 Cocos Creator 是一个 GUI 编辑器,它的引擎运行时不在 npm 上,命令行里装不了也跑不起来。所以本卷采取的策略是:把「能跑」的部分做到极致(L1 全部真跑、真测、真截图),把「不能跑」的部分如实标注(L3),中间的 Cocos 脚本用真实引擎类型声明做类型检查(L2)。 你看到的每一段 mini2d 代码,都是在 Node 里跑过、在浏览器里画过、被单测断言过的。
版本与技术口径
| 项 | 版本 | 说明 |
|---|---|---|
| Cocos Creator | 3.8.8 | 全书锁定,对应 @cocos/creator-types@3.8.8 |
| Node.js | 26.5.0 | 只做 TypeScript 类型剥离,因此代码限可擦除语法 |
| TypeScript | 7.0.2 | mini2d 侧使用;禁 enum / namespace / 构造函数参数属性 |
| vitest | 5.0.3 | L1 逻辑单测 |
| Vite | 8.3.4 | 打包成单文件 bundle |
| Playwright | 1.59.1 | 无头浏览器截图回归 |
关于「可擦除语法」:Node 26 直接运行 TypeScript 时,只剥离类型、不做语法转换。所以 enum、namespace、构造函数参数属性这些「需要生成运行时代码」的写法不能用。本书一律用 const 对象 + as const 代替 enum,用模块导出代替 namespace。这不是限制,而是一种更贴近现代 TS 的写法。
全书结构
全书 18 章分五个部分,每章 3 节,每章末节是 Cocos 对照。此外有 1 篇目录(本页)、1 篇序、1 篇前言与 4 篇附录。
第一部分:地基(第 1–3 章)
先把「一帧」这件事想清楚,再让画面动起来。
| 节 | 标题 | 一句话 |
|---|---|---|
| 1.1 | 环境与仓库骨架 | 建好 Node 26 + TS + vitest + Playwright,接通 Cocos 类型检查 |
| 1.2 | 游戏的心智模型:帧、时间、坐标系 | 离散时间、坐标原点与 y 轴方向的约定 |
| 1.3 | 第一个可跑循环:requestAnimationFrame 与固定步长 | 固定步长累积器让逻辑与帧率解耦 |
| 2.1 | Canvas2D 绘制与坐标变换 | 手写平移 / 旋转 / 缩放矩阵 |
| 2.2 | 精灵、纹理与图集切分 | 源矩形切图、锚点与九宫格 |
| 2.3 | 相机、视口与分辨率适配 | 世界坐标到屏幕坐标的映射 |
| 3.1 | 场景图与节点树 | 父子变换与脏标记 |
| 3.2 | 绘制顺序、层级与遮罩 | 谁盖谁,以及裁剪区域 |
| 3.3 | 批处理与 Draw Call | 合批条件与纹理切换代价 |
第二部分:时间、输入与对象(第 4–6 章)
让运动稳定、让操作跟手、让代码可组合。
| 节 | 标题 | 一句话 |
|---|---|---|
| 4.1 | 帧率无关的移动与 deltaTime | 为什么乘 deltaTime 就帧率无关 |
| 4.2 | 固定步长物理与渲染插值 | 物理稳定与画面顺滑兼得 |
| 4.3 | 暂停、时间缩放与慢动作 | 时间缩放与 UI 计时隔离 |
| 5.1 | 输入事件模型与坐标换算 | 屏幕坐标到世界坐标,处理 DPR |
| 5.2 | 触摸手势与多点触控 | 点击、滑动、长按与捏合 |
| 5.3 | 输入缓冲与手感 | 跳跃宽容与连击窗口 |
| 6.1 | 组件模型:从继承到组合 | 用组合替代深继承 |
| 6.2 | 生命周期与消息分发 | 组件生命周期的固定顺序 |
| 6.3 | 序列化与数据驱动配置 | 参数进配置,改数值不改代码 |
第三部分:表现(第 7–11 章)
碰撞、动画、声音、资源、界面——玩家真正看得见摸得着的部分。
| 节 | 标题 | 一句话 |
|---|---|---|
| 7.1 | AABB、圆形与 SAT 碰撞检测 | 三种检测各自的适用场景 |
| 7.2 | 空间划分与宽相 | 网格与四叉树把粗筛降下来 |
| 7.3 | 碰撞响应、触发器与分层掩码 | 穿透、推出与谁和谁碰 |
| 8.1 | 帧动画与精灵表播放 | 时间轴驱动与事件帧 |
| 8.2 | 补间与缓动曲线的数学 | 手写缓动函数与补间队列 |
| 8.3 | 属性动画与状态驱动表现 | 表现由状态驱动 |
| 9.1 | 音频播放与音效池 | 复用播放实例 |
| 9.2 | BGM、淡入淡出与音量总线 | 音量总线与淡入淡出 |
| 9.3 | 移动端音频限制与解锁 | 自动播放限制与首次交互解锁 |
| 10.1 | 资源清单与依赖图 | 清单与依赖静态分析 |
| 10.2 | 异步加载、进度与预加载 | 并发加载与进度汇报 |
| 10.3 | 引用计数与资源释放 | 何时真正释放 |
| 11.1 | 布局系统:锚点、对齐与适配 | 用锚点摆脱绝对坐标 |
| 11.2 | 列表虚拟化与滚动性能 | 只渲染可见项 |
| 11.3 | 弹窗栈与界面状态机 | 栈管层级,状态机管跳转 |
第四部分:系统与玩法(第 12–14 章)
从「能跑」到「像个游戏」。
| 节 | 标题 | 一句话 |
|---|---|---|
| 12.1 | 游戏状态机 | 加载 / 主菜单 / 游戏 / 暂停 / 结算 |
| 12.2 | 序列化格式、版本与迁移 | 存档版本号与迁移函数 |
| 12.3 | 本地存储与云存档冲突 | 两份存档的合并策略 |
| 13.1 | 有限状态机与行为树 | 可组合的敌人行为 |
| 13.2 | 寻路:A* 与导航网格 | 手写 A* 与启发函数 |
| 13.3 | 关卡数据与程序化生成 | 约束 + 种子生成可玩关卡 |
| 14.1 | 结算管线与帧对齐 | 伤害排队与顺序稳定 |
| 14.2 | 技能与效果系统:数据驱动 | 效果原子组合出技能 |
| 14.3 | 经济与掉落表 | 权重掉落与保底 |
第五部分:质量与交付(第 15–18 章)
让它可调试、可测试、可发布。
| 节 | 标题 | 一句话 |
|---|---|---|
| 15.1 | 调试绘制与可视化 | 把碰撞盒与路径画出来 |
| 15.2 | 帧率、内存与性能剖析 | 定位掉帧的真凶 |
| 15.3 | 开发者控制台与作弊命令 | 游戏内控制台 |
| 16.1 | 纯逻辑单测:vitest 与假时钟 | 把逻辑变成可断言事实 |
| 16.2 | 渲染端到端测试:Playwright 截图 | 可复现的渲染回归 |
| 16.3 | 确定性回放与回归 | 录制输入并回放 |
| 17.1 | 构建流程与产物体积分析 | 打包与体积构成 |
| 17.2 | 多端发布:H5 / 微信小游戏 / 原生 | 三端各自的约束 |
| 17.3 | Cocos 对照:构建面板与多平台发布 | 对照引擎的构建面板 |
| 18.1 | 同一款游戏的两套实现对照 | mini2d 版与 Cocos 版并排 |
| 18.2 | 迁移清单:mini2d → Cocos Creator | 迁移检查清单 |
| 18.3 | 回顾与路线:进入实战卷 | 回顾与衔接 |
前置与附录
| 篇 | 标题 | 一句话 |
|---|---|---|
| 序 | 序:为什么从零写一个 2D 运行时 | 本卷的写作动机与取舍 |
| 前言 | 前言:本书怎么读 | 写给谁、版本口径、不写什么 |
| 附 A | 附录 A.mini2d API 与模块速查 | 核心类型签名与断言法 |
| 附 B | 附录 B.Cocos Creator 3.8 工程结构与 cc.d.ts 速查 | 工程结构与类型反查 |
| 附 C | 附录 C.环境与离线复现速查 | 环境配置与零网络复现 |
| 附 D | 附录 D.常见错误与 FAQ | 高频报错与修法 |
八到十周学习计划
按路径 A 走,一个参考排期:
| 周次 | 章节 | 产出 |
|---|---|---|
| 第 1 周 | 第 1–2 章 | 能跑的主循环 + 能画方块的渲染器 |
| 第 2 周 | 第 3–4 章 | 场景图 + 固定步长物理 |
| 第 3 周 | 第 5–6 章 | 输入手感 + 组件模型 |
| 第 4 周 | 第 7–8 章 | 碰撞检测 + 动画系统 |
| 第 5 周 | 第 9–11 章 | 音频 + 资源 + UI |
| 第 6 周 | 第 12–14 章 | 存档 + AI + 玩法数值 |
| 第 7 周 | 第 15–16 章 | 调试工具 + 测试体系 |
| 第 8 周 | 第 17–18 章 | 打包发布 + 两套实现对照 |
| 第 9–10 周 | 复习 + 动手改 | 把《方块冲刺》改成自己的游戏 |
常见问题速查
| 你遇到的问题 | 去看 |
|---|---|
| 角色移动速度随帧率变化 | 4.1 帧率无关的移动 |
| 物理偶尔穿墙、抖动 | 4.2 固定步长 、7.3 碰撞响应 |
| 暂停后 UI 动画也停了 / 没停 | 4.3 时间缩放 |
| 触摸位置和画面对不上 | 5.1 输入坐标换算 |
| 跳跃手感发飘、连跳不跟手 | 5.3 输入缓冲 |
| 图集里切出来的图错位 | 2.2 图集切分 |
| 画面上东西盖错顺序 | 3.2 绘制顺序 |
| Draw Call 太高 | 3.3 批处理 |
| 切场景后内存一直涨 | 10.3 引用计数 |
| 长列表滚动卡顿 | 11.2 虚拟列表 |
| 老玩家的存档读不出来 | 12.2 存档迁移 |
| 伤害数字忽大忽小、顺序乱 | 14.1 结算管线 |
| 测试跑两次结果不一样 | 16.1 确定性单测 |
| 打包出来体积太大 | 17.1 体积分析 |
| 更多报错原文 | 附录 D |
相关阅读
- 游戏开发专题 — 站内游戏开发的专题文章总入口
- 游戏引擎专题 — 引擎架构与渲染管线的专题讨论
- 图形学专题 — 渲染管线与图形 API 的系统文章
- TypeScript 专题 — 类型系统与工程实践
- 书稿专题 — 全部在线电子书与创作手记
准备好了就翻开序 ,或者直接跳到第 1 章 1.1 环境与仓库骨架 开始动手。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。