我所理解的Cocos2d-x(完全基于Cocos2d-x3.0,深度剖析计算机图形学,OpenGL ES及游戏引擎架构,全面提升游戏开发相关知识)
秦春林 著
ISBN 978-7-121-24625-8
2014年11月出版
定价:79.00元
404页
16开
内容提要
《我所理解的Cocos2d-x》针对最新的 Cocos2d-x3.x版本,介绍了Coco2d-x游戏引擎的基本架构、渲染机制,以及各个子模块的功能和原理,并结合OpenGL ES图形渲染管线,深入探讨了游戏开发中涉及的相关图形学的知识,内容包括:Cocos2d-x的基本架构及渲染机制、纹理相关的知识、OpenGL ES 2.0渲染管线、计算机字体的绘制、多分辨率支持、事件分发、碰撞与物理引擎、游戏对象模型架构、Genius-x开源框架、脚本在游戏引擎中的架构等。《我所理解的Cocos2d-x》偏重讲解每个知识模块的概念及原理,使读者能够透过现象看到其背后的工作机制,所以本书在内容组织上并不是围绕Cocos2d-x的接口使用来展开,而是按照通用游戏引擎架构及图形学的内容进行组织。
《我所理解的Cocos2d-x》面向中、高级开发者,可作为初级开发者进阶的教程,也可作为高校游戏引擎架构及图形学相关专业的参考教材。
目录
第1章 全新的Cocos2d-x 3.0 1
1.1 Cocos2d-x 3.0的历史意义 1
1.1.1 回归C++风格 2
1.1.2 更灵活的渲染架构 2
1.1.3 更自由的发展 2
1.2 Cocos2d-x 3.0的新特性 3
1.2.1 使用C++风格 3
1.2.2 跨平台的Label 6
1.2.3 新的渲染系统 6
1.2.4 统一的消息分发 8
1.2.5 物理引擎集成 9
1.2.6 新的数据结构 10
1.2.7 其他 14
1.3 Cocos2d-x引擎展望 15
1.3.1 3D 16
1.3.2 Cocos Code IDE 16
1.4 本章小结 17
第2章 Cocos2d-x架构一瞥 19
2.1 Cocos2d-x引擎系统总览 19
2.2 Cocos2d-x内存管理机制 21
2.2.1 C++显式堆内存管理 21
2.2.2 C++ 11中的智能指针 22
2.2.3 为什么不使用智能指针 23
2.2.4 垃圾回收机制 23
2.2.5 Cocos2d-x内存管理机制 24
2.2.6 Cocos2d-x中的智能指针 29
2.2.7 怎样进行内存管理 35
2.3 UI树及运行时游戏对象 35
2.3.1 位置与变换 35
2.3.2 坐标系 36
2.3.3 UI树 39
2.3.4 UI元素与内存管理 45
2.4 应用程序架构 46
2.4.1 游戏生命周期 46
2.4.2 窗口尺寸 48
2.4.3 场景管理 48
2.4.4 游戏循环 49
2.5 实时更新游戏对象 52
2.5.1 帧率 52
2.5.2 Scheduler 53
2.5.3 时间线 54
2.5.4 逻辑更新优先级 55
2.5.5 性能问题 56
2.6 Cocos2d-x的主线程 56
2.6.1 在主线程中执行异步处理 57
2.6.2 纹理的异步加载 58
2.6.3 异步处理的单元测试 60
2.7 本章小结 60
第3章 OpenGL ES 2.0概览 62
3.1 图形处理器简介 62
3.2 什么是OpenGL ES 63
3.3 OpenGL ES 2.0渲染管线 64
3.3.1 顶点数组 65
3.3.2 顶点着色器 66
3.3.3 图元装配 66
3.3.4 光栅化 69
3.3.5 片段着色器 70
3.3.6 片段测试 70
3.4 渲染管线中的并行计算 71
3.5 构建高性能的渲染引擎 72
3.6 帧缓冲 73
3.7 本章小结 74
第4章 全新的绘制系统 76
4.1 新绘制系统的特点 76
4.2 绘制系统概览 77
4.3 RenderCommand 79
4.4 RenderQueue 80
4.5 GroupCommand 81
4.6 Render 84
4.6.1 RenderCommand的排序 84
4.6.2 QuadCommand 85
4.7 元素的可见性 87
4.8 绘制的时机 89
4.9 示例:自定义RenderCommand 91
4.10 本章小结 95
第5章 纹理 96
5.1 光栅化 96
5.1.1 多重采样 97
5.1.2 纹理坐标 98
5.2 像素矩形 99
5.2.1 像素存储模式 99
5.2.2 纹理数据的传输 99
5.2.3 解包 100
5.3 客户端图像格式 103
5.3.1 纹理格式的对应关系 104
5.3.2 图像数据格式转换 105
5.4 纹理对象和加载纹理 107
5.5 纹理单元与多重纹理 109
5.6 纹理缩放 110
5.6.1 纹理缩小 110
5.6.2 纹理放大 111
5.6.3 在Cocos2d-x中设置过滤模式 112
5.7 多级纹理 113
5.7.1 多级纹理过滤模式 113
5.7.2 多级纹理的上传 114
5.7.3 多级纹理的生成 115
5.8 纹理压缩 116
5.8.1 压缩纹理的特点 116
5.8.2 压缩纹理的实现 117
5.8.3 在Cocos2d-x中使用压缩纹理 118
5.8.4 PVRTC和PVRTC2 120
5.8.5 ETC 122
5.8.6 针对不同设备使用不同的压缩纹理 123
5.9 纹理缓存管理 123
5.9.1 纹理的生命周期 124
5.9.2 用TextureCache来管理纹理 125
5.9.3 场景过渡中的资源管理 127
5.9.4 Android下的纹理恢复处理 130
5.10 纹理所占内存的计算 131
5.11 使用纹理最佳实践 133
5.11.1 硬件层面 133
5.11.2 程序层面 133
5.11.3 资源层面 134
5.12 本章小结 135
第6章 精灵 137
6.1 用Sprite绘制一个矩形区域 137
6.1.1 V3F_C4B_T2F_Quad结构体 138
6.1.2 使用QuadCommand进行绘制 139
6.1.3 将Sprite作为子元素 140
6.2 Sprite的绘制属性 140
6.2.1 颜色混合 141
6.2.2 颜色叠加 144
6.3 Alpha预乘 148
6.4 精灵表 150
6.5 精灵动画 152
6.6 批绘制还是自动批绘制 154
6.6.1 SpriteBatchNode 154
6.6.2 TextureAtlas 156
6.6.3 SpriteBatchNode的特点和限制 157
6.7 部分拉伸:九宫格 157
6.8 本章小结 158
第7章 OpenGL ES着色语言 161
7.1 概览 161
7.2 基础类型 162
7.2.1 空类型 163
7.2.2 布尔类型 163
7.2.3 整型 163
7.2.4 浮点型 163
7.2.5 矢量 164
7.2.6 矩阵 164
7.2.7 采样器 164
7.2.8 结构体 165
7.2.9 数组 165
7.3 存储限定符 166
7.3.1 默认限定符 167
7.3.2 常量限定符 167
7.3.3 属性限定符 167
7.3.4 全局限定符 168
7.3.5 易变量限定符 169
7.4 构造器 170
7.4.1 标量的转换构造 170
7.4.2 矢量和矩阵构造器 171
7.4.3 结构体构造器 172
7.5 矢量的分量 173
7.6 矩阵的分量 174
7.7 结构体和成员 174
7.8 矢量和矩阵操作符 175
7.9 本章小结 176
第8章 OpenGL ES着色程序 177
8.1 顶点和顶点数组 177
8.1.1 图元与顶点 178
8.1.2 顶点属性状态 178
8.1.3 顶点数组 180
8.2 顶点缓冲对象 185
8.2.1 顶点数组缓冲对象 187
8.2.2 索引数组缓冲对象 188
8.2.3 使用VAO缓存顶点数组状态 190
8.3 着色器程序 192
8.3.1 着色器程序字符串 192
8.3.2 着色器的加载和编译 193
8.3.3 着色器程序对象 195
8.4 Cocos2d-x着色器子系统 196
8.4.1 GLProgram与Node之间的关系 197
8.4.2 GLProgramState 199
8.4.3 着色器程序的使用过程 202
8.4.4 GLProgramState的管理 204
8.4.5 GLProgramState的限制 205
8.5 顶点着色器 206
8.5.1 输入参数 206
8.5.2 顶点坐标输出参数 207
8.5.3 易变量输出参数 208
8.6 片段着色器 209
8.6.1 输入参数 210
8.6.2 纹理采样 210
8.6.3 输出参数 211
8.7 着色器编辑工具 211
8.8 示例 213
8.8.1 使用ETC压缩纹理 214
8.8.2 动态设置着色器参数 217
8.9 着色器程序最佳实践 220
8.10 本章小结 220
第9章 帧缓冲 223
9.1 GroupCommand 223
9.1.1 使用GroupCommand的流程 224
9.1.2 GroupCommand的限制 225
9.2 帧缓冲 226
9.2.1 绑定和管理帧缓冲 227
9.2.2 将图像附加到帧缓冲 228
9.2.3 渲染缓冲对象 228
9.2.4 将Renderbuffer附加到帧缓冲 230
9.2.5 将Texture附加到帧缓冲 230
9.2.6 帧缓冲完成状态 231
9.3 RenderTexture 234
9.3.1 RenderTexture的初始化 235
9.3.2 RenderTexture的绘制 238
9.3.3 ReadPixels 239
9.3.4 RenderTexture的限制及用途 240
9.4 本章小结 240
第10章 片段操作 242
10.1 片段操作简述 242
10.2 逻辑缓冲区 243
10.2.1 位平面 244
10.2.2 按位计算 245
10.3 片段测试 248
10.3.1 模板测试 248
10.3.2 深度测试 250
10.3.3 模板测试的步骤 251
10.3.4 片段测试的用途 252
10.4 全缓冲区操作 254
10.4.1 控制缓冲区的更新 254
10.4.2 清理缓冲区 254
10.5 ClippingNode 255
10.5.1 ClippingNode的绘制流程 255
10.5.2 ClippingNode的模板测试分析 256
10.6 本章小结 258
第11章 多分辨率支持 259
11.1 概述 259
11.2 设计分辨率 260
11.2.1 缩放策略 261
11.2.2 调整元素位置 262
11.2.3 几个有用的变量 263
11.2.4 使用屏幕分辨率 264
11.2.5 视口设置 264
11.2.6 什么时候缩放了 265
11.3 资源分辨率 267
11.3.1 资源分辨率的设置 267
11.3.2 真实分辨率InPixels 268
11.3.3 什么时候缩放资源 269
11.4 本章小结 270
第12章 事件分发 272
12.1 概述 272
12.1.1 什么是事件 272
12.1.2 事件的工作机制 272
12.1.3 事件系统的特点 273
12.2 订阅者 274
12.2.1 事件类型 275
12.2.2 注册与管理订阅者 276
12.3 事件的分发 278
12.3.1 订阅者的排序 280
12.3.2 嵌套事件 282
12.3.3 在事件分发中修改订阅者 282
12.3.4 停止分发事件 283
12.4 事件与Node 284
12.4.1 暂停与恢复 284
12.4.2 删除订阅者 285
12.5 触摸事件 285
12.5.1 EventListenerTouchAllAtOnce 286
12.5.2 EventListenerTouchOneByOne 286
12.5.3 单点和多点触摸之间的关系 288
12.5.4 触摸点的位置判断 288
12.5.5 可见性与触摸事件 289
12.6 其他 289
12.6.1 其他操作系统事件 290
12.6.2 EventCustom 290
12.6.3 内存管理 290
12.6.4 回调与返回值 291
12.6.5 单元测试 291
12.6.6 其他事件 291
12.7 本章小结 292
第13章 字体的故事 293
13.1 计算机字体的历史 293
13.2 轮廓字形概述 294
13.2.1 点 295
13.2.2 轮廓 295
13.2.3 轮廓的方向 296
13.2.4 轮廓的交叉 296
13.2.5 混合轮廓字形 296
13.2.6 字形格子 297
13.3 FreeType字体引擎 297
13.3.1 字体文件及字形索引 298
13.3.2 字符度量 298
13.3.3 FreeType字形解析过程 299
13.3.4 FreeType字形装载 301
13.4 FontAtlas 304
13.4.1 Font 305
13.4.2 FontAtlasCache 308
13.5 Label 309
13.5.1 通用属性 310
13.5.2 Font字符集 312
13.5.3 轮廓字体的缩放 312
13.5.4 特效 316
13.6 使用字体的最佳实践 319
第14章 动画系统 321
14.1 概述 321
14.2 线性插值 323
14.2.1 标量插值 323
14.2.2 矢量插值 323
14.2.3 变换矩阵插值 324
14.2.4 插值在动画系统中的运用 324
14.3 给元素添加动画 326
14.3.1 Action是一个自描述的对象 326
14.3.2 在Node上执行动画 327
14.3.3 控制动画的动画 329
14.4 动画系统架构 331
14.4.1 Speed 333
14.4.2 缓动函数 333
14.4.3 自定义动画——精灵闪白 334
14.5 本章小结 337
第15章 碰撞及物理引擎 339
15.1 物理引擎概述 339
15.2 碰撞检测系统 340
15.2.1 刚体 340
15.2.2 接触和碰撞 343
15.2.3 碰撞查询 348
15.3 刚体动力学 349
15.3.1 控制刚体的运动 349
15.3.2 碰撞响应 350
15.3.3 约束 351
15.4 整合物理引擎 352
15.4.1 刚体与可视对象 352
15.4.2 物理世界 355
15.4.3 游戏循环阶段 357
15.5 预处理与工具 357
15.6 本章小结 358
第16章 运行时游戏对象模型 360
16.1 概述 360
16.2 运行时游戏对象模型 361
16.2.1 以对象为中心的架构 362
16.2.2 组件模型 364
16.2.3 以属性为中心的架构 367
16.3 Entity Component System 369
16.3.1 属性结构 370
16.3.2 分离数据与行为 371
16.3.3 数据驱动 372
16.4 对象查询与消息通信 373
16.4.1 根据唯一标识符查询 374
16.4.2 根据类型查询 375
16.4.3 面向类型编程 375
16.4.4 游戏对象数据库 376
16.5 实时更新游戏对象 377
16.5.1 更新的性能优化 377
16.5.2 更新的时序 377
16.6 本章小结 379
第17章 Genius-x开源框架 381
17.1 Genius-x是什么 381
17.1.1 Genius-x架构一览 382
17.1.2 Genius-x项目结构及使用 384
17.2 游戏对象模型 385
17.2.1 Entity 385
17.2.2 Component 388
17.2.3 System 391
17.2.4 ECSManager 394
17.2.5 数据驱动 397
17.2.6 NodeCom 399
17.2.7 对象的层级结构 403
17.3 数据格式、加载及串流 403
17.3.1 数据格式 404
17.3.2 文件加载和管理 405
17.3.3 游戏世界的串流 406
17.4 游戏通用系统 407
17.5 共享组件 409
17.6 示例 409
第18章 脚本 411
18.1 脚本的概念 411
18.1.1 脚本语言的特征 412
18.1.2 Lua脚本语言 412
18.1.3 脚本所需的架构 413
18.2 运行时脚本语言的功能 415
18.2.1 对原生编程语言的接口 415
18.2.2 游戏对象句柄 416
18.2.3 在脚本中接收及处理事件 423
18.2.4 发送事件 427
18.2.5 面向对象脚本语言 427
18.3 Lua bindings 430
18.3.1 生成绑定代码 430
18.3.2 在程序中使用绑定代码 431
18.3.3 自定义绑定 432
18.4 在Lua中使用Genius-x 433
18.4.1 配置环境 433
18.4.2 创建Component脚本 433
18.4.3 创建System脚本 434
18.4.4 其他接口 435
18.5 本章小结 435
精彩节摘
第16章 运行时游戏对象模型
到目前为止,我们讨论的所有内容都可以称之为低阶引擎系统,例如Renderer如何将网格绘制到屏幕上,纹理如何被使用,字体如何被绘制,如何从人体学接口设备获取玩家输入信息,如何处理物体的碰撞,以及如何对物体执行动画等。这些几乎都是和游戏性无关的一些基础功能。
当开始设计游戏的时候,开发者面对的往往是一个更上层的,可以称之为游戏性(Gameplay)基础系统的高阶引擎系统,例如怎样表示游戏中的对象,怎样组织它们的行为和状态,设计师怎样通过数据驱动来快速修改关卡及游戏配置,怎样高效有序地组织游戏对象之间的逻辑更新等。这些笔者称之为游戏性架构(Gameplay Architecture),或者很多开发者称之为游戏架构。理论上,游戏性架构的一些理论和实践甚至可以和游戏引擎无关。
当然,游戏性架构其实涉及很多内容,例如它可以包括运行时游戏对象模型、关卡及串流、实时更新游戏对象模型、事件分发及脚本系统等。本章将会聚焦于运行时游戏对象模型,讲述常见的几种游戏对象设计的概念、方式及优缺点。
16.1 概述
在所有游戏性架构相关的内容中,运行时游戏对象模型可能是最复杂的系统,并且不同的游戏引擎呈现出的差异极大。例如Unity3D提供的组件模型,虚幻引擎提供的面向对象继承的模型,其他一些游戏例如《末日危城(Dungeon Siege)》则使用一种不同于两者的基于数据驱动的游戏对象模型。
这些不同的游戏对象模型之间呈现出很大的设计思维及使用上的差异,但是它们往往都提供或者必须具备一些通用的功能,这些包括但不限于:
(1)管理游戏对象的创建及销毁。游戏中经常会动态创建各种游戏对象,例如一个塔防游戏会定时出现一些小怪物,***在撞击到目标时立即被销毁等。许多游戏引擎都提供一种统一的动态创建、销毁游戏对象的方式,并管理游戏对象的内存及资源,例如第17章即将讲述的Genius-x框架中使用createEntity()、removeEntity(entity)来动态创建和销毁一个游戏对象。但是在Cocos2d-x中却不是通过统一的方式创建和销毁游戏对象,它使用每个Node子类自己的构造函数来创建,并使用一种特殊的方式管理内存(参见第2章)。
(2)联系底层游戏引擎。每个游戏对象要能够通过某种方式访问底层的游戏引擎系统,例如能够渲染三角形网格、执行碰撞检测,对角色执行动画等。在Unity3D引擎中,每个游戏对象(GameObject)可以通过添加一个与底层引擎功能相关的组件(Componment)来访问底层引擎系统。Cocos2d-x的Node类则直接集成了物理模拟、动画、实时逻辑更新等接口。
(3)实时模拟对象行为。游戏是一个高度实时的系统,游戏对象的状态、行为在每一帧都可能会随着时间发生变化,这需要一套高效的游戏对象更新机制。对象可能需要以特定的逻辑次序进行更新。此外,除了逻辑次序,游戏对象之间还可能存在依赖关系,需要按照一定的次序更新(关于游戏对象更新的次序会在本章后面讲述)。
(4)定义新游戏对象类型。在开发过程中,随着游戏需求的改变和演进,游戏对象模型必须有足够的弹性,可以容易地加入新的对象类型。理想情况下,新的游戏类型应可以完全用数据驱动的方式定义,但是在实际情况中,大部分新增游戏类型都需要程序员的参与。在Genius-x框架中,新的不同行为的组合类型可以通过修改数据文件来实现,而新的行为则可以通过脚本来实现,然后修改数据文件来添加新的行为。
(5)唯一的对象标识符。游戏世界可能会包含成百上千的游戏对象,在运行时必须能够识别和找到想要的对象,这意味着每种对象需要有某种唯一标识符。例如在Cocos2d-x 中可以通过给一个Node指定一个字符串名称,然后通过字符串标识符查找一个游戏对象。
(6)游戏对象查询。除了上面按游戏唯一标识符查询游戏对象,游戏性系统还需要一些更高级的查询方式,例如找到某种类型的游戏对象,或者某个范围的敌人等。在面向组件或者属性的架构中,游戏对象是以组件/属性为单位存储的,很容易查找具有某个属性类型的游戏对象组合,并且这种查找游戏对象的方式对数据驱动更友好,笔者称之为面向类型编程。
除了上述提到的这些,运行时游戏对象模型还包括有限状态机,用于同一个网络内的对象复制、对象序列化和持久性存档等。
作者简介
秦春林:自大学开始自学编程,先后从事过工作流软件,云计算,Web等相关的工作。2011年开始进入游戏开发领域,主持并移植了Cocos2d-x-for-XNA项目。喜欢技术分享,发起并组织了北京快乐技术沙龙,多次作为讲师参与微软,CSDN,51CTO以及9RIA等组织的各类技术培训和讲座。参与了手游项目《天降》的开发,目前主要的兴趣方向是计算机图形学和游戏引擎架构,致力于用软件技术丰富游戏世界的表现及品质。
媒体评论
2014年,对于Cocos2d-x可以说是具有里程碑意义的一年:3.x大版本更新、向3D领域正式进军、北大/浙大等重点高校开课、与ARM/微软/Intel巨头深入合作、在日本等市场实现后进者逆袭……引擎团队的不懈努力得到了丰厚的回报。
Cocos2d-x 3.0版本的这一次飞跃主要实现了三大优化:一是新的渲染器,可创建渲染队列,可简单地实现批量渲染,跨平台也非常容易;二是新修改过的API,将语言用法改为C++程序员更习惯的使用方式,稳定性与可读性得到提升;三是性能再次提升优化,利用自动裁剪、自动批处理技术,性能得到很大提升,兼容性方面在中国安卓平台上也做到非常好用。
在版本跟进方面,秦春林的速度是最快的。现在你看到的这本《我所理解的Cocos2d-x》是国内第一本直接从Cocos2d-x3.0版本入手的书籍,直接从更高的起点起步,可以说是国内最新。
本书由浅入深,共分18个章节,从Cocos2d-x 3.0及架构开始,逐块剖析引擎的各个特性,同时搭配OpenGL ES的相关使用。在最后一章,秦春林还介绍了他自己基于组件架构模型写的开源框架,可以说是一本很好的Cocos2d-x高阶书籍,值得一读。
另外,秦春林的团队“魂世界”采用Cocos2d-x开发的作品《天降》在今年也取得了非常好的成绩,已被乐逗游戏以2000万元的高价代理,是一款很酷的电竞手游。我本人非常期待,希望这款Cocos2d-x游戏能够取得更好的成绩。
最后,祝秦春林的书本大卖、游戏火爆,也祝更多的团队能够从Cocos引擎中受益。
Cocos2d-x游戏引擎作者
王哲
前言
我与Cocos2d-x结缘于2011年,那个时候我所在的公司OpenXLive与Cocos2d-x团队合作移植Cocos2d-x游戏引擎到WP7平台,它采用C#语言基于XNA来实现,我是该项目的负责人。然而不久,微软就用支持C++原生语言的WP8替代了WP7,该项目也逐渐被开发者淡忘。没想到三年后我却会为Cocos2d-x写一本书,这三年,我和Cocos2d-x都在成长。
开源是我认为软件最富魅力的部分,它给予我们阅读和修改源代码的自由。开源对人类和科技进步的贡献是巨大的,如今,大多数软件系统都有着各种各样开源软件的影子。开源代码对技术人员的成长有着难以估量的价值,例如,没有开源的Cocos2d-x,我就难以写出本书中的很多内容。
本书定位为一本进阶的书籍,它着重于讲述Cocos2d-x引擎各个功能及组件背后的实现原理。因此,本书并没有严格按照Cocos2d-x引擎本身的功能展开描述,而是从这些功能中抽象出一些设计或者架构层面的内容进行讨论。例如本书没有分别讲述精灵、地图、粒子特效等的接口使用,而是从纹理、渲染方式等多个方面来讲述这些元素背后的工作机制;而OpenGL ES、物理引擎和脚本等内容也几乎是可以脱离于Cocos2d-x进行学习和理解的。
这就是本书标题的来源,也是本书与同类书籍在内容编排上的最大不同。我希望写一本书,它可以让读者站在一个系统性的高度对游戏引擎的一些架构设计及实现进行理解,从而不但提升和扩充自己的知识结构,更能够在实际开发中去灵活解决各个层面的技术问题。本书同时追求系统性和实践性的平衡,例如对于纹理部分,除了总结纹理相关的所有知识,也通过一些示例来演示它在各个层面的具体使用。
本书共分18章。
第1~4章介绍了Cocos2d-x引擎的基本架构及新的绘制系统。这部分内容包括:Cocos2d-x的内存管理机制,UI树的遍历及结构,应用程序的生命周期,游戏循环的各个阶段,以及在Cocos2d-x中驱动各个子系统进行逻辑更新的机制和工作原理。这部分也介绍了Cocos2d-x 3.x新的数据结构,并详细描述了新的渲染系统。总之,在这一部分,读者可以对Cocos2d-x的基本架构有比较系统的了解。
第5~10章围绕OpenGL ES图形渲染管线进行介绍。这部分从纹理讲起,详细讲述了纹理的存储格式、传输、缩放、压缩及多重纹理等相关知识;第8章详细讲述了顶点数组的结构、顶点属性的绑定及传输、着色器程序的编译及链接,以及Cocos2d-x新的着色器子系统,并举例在Cocos2d-x中使用着色器的流程和怎样使用多重纹理。这部分也对顶点着色器和片段着色器两个阶段在图形渲染管线中的作用进行了详细描述。
第9、10章讲述了OpenGL ES图形渲染管线的最后两个阶段:帧缓冲和片段操作,并以Cocos2d-x中对这两个阶段的应用RenderTexture和ClippingNode为例进行讲解。这样,读者将对整个渲染管线的每一个阶段都能有所了解,并且能够结合Cocos2d-x中的使用去思考每一个阶段的意义和作用,从而对图形渲染管线有更深刻的了解。这也是本书最具特色的部分。
第10~15章讲述了Cocos2d-x的一些子系统,包括事件分发、多分辨率支持、动画系统及物理引擎整合。其中物理引擎部分也是我比较喜欢的章节,这部分讲述了一些通用的物理引擎的架构及其使用,以及怎样和游戏引擎进行整合。
第16~18章探讨应该怎样去设计和管理游戏世界中的对象。第16章讲述了常见的对象模型、组件模型、属性模型之间的概念、区别及优缺点;第17章则以属性模型为例,讲述了一个游戏对象模型应该怎样设计;第18章探讨了时下最流行的脚本相关的内容,但是与仅仅讨论脚本使用不同的是,我们站在一个游戏引擎的高度去讨论脚本的架构,这样读者甚至能设计自己的脚本模型。这一部分内容具有对前端架构设计的高度总结性与实践性,不管是对经验丰富的读者还是初学者,相信都具有一定的启发性。
另外,本书在写作之初并没有构建出整本书的内容结构,在写前面的章节时我甚至不知道最后几章的内容和结构会是怎样的。在开始写每一章的时候,我不会首先去给自己描绘一个目录结构,而是首先把所有相关的内容列出来,如果之中有我不熟悉的内容,或者有Cocos2d-x以外的一些知识,我则会首先停下写作去把这些内容整理出来。例如关于ECS部分的内容就是基于Cocos2d-x社区的一些讨论,我花了很多时间去学习和理解。当最后所有相关的内容整理为一个列表时,我就知道该怎么去写作这部分的内容。因此,在这本书的目录结构中,读者找不到任何同类书籍类似的内容结构,因为这完全是基于个人的理解及知识结构体系去写作的一本书。
所以,对我而言这本书还有一个有意义的目标,我希望透过这样的方式去探讨一种系统性的学习方法。当你开始学习某个知识点时,不要把自己限定在该知识点处,而是首先从该知识点进行适当的扩展,列出该知识点相关的所有内容,再逐个深入学习和研究细节,最后反过来整理该知识点的结构体系。这样不仅能够更深入地学习该知识点,还能够延伸知识的广度,所以本书有大量超出Cocos2d-x以外的内容,这些内容又是与Cocos2d-x紧密相关的。希望读者在阅读过程中能够感受到这样一种写作风格和方法。
本书是一本进阶类书籍,阅读本书,你需要对Cocos2d-x和C++有基本的了解。如果你是一名新手,可以首先阅读同类书籍中相对比较入门的书籍,否则本书的一些章节可能会给你造成一定的困惑。
学习知识最好的方法永远是多读几遍,书中关于OpenGL ES和游戏对象模型部分的内容可能需要多读几次才能更加深入地理解相关的概念。当然,如果你在阅读过程中遇到什么障碍,随时可以通过电子邮件或者我的博客等多种方式和我进行探讨。
本书可以作为Cocos2d-x开发学习的书籍,也可以作为单独的OpenGLES相关的教材,游戏对象模型部分的内容也可以作为设计游戏引擎架构的参考资料。本书也可以作为高校游戏及图形学相关专业的参考教程。
最后,由于个人经验有限、思维有限,书中难免会出现一些错误和疏漏。真诚地希望读者可以将这些错误的地方反馈给出版社,我们会及时地列出勘误,以帮助更多的读者更好地学习。
秦春林
2014年7月25日