我是如何写游戏引擎的

背景

首先说明,我写的引擎是在没智能设备的嵌入式环境下。具体就是:

  • 没有OpenGL
  • 没有C++
  • 没有标准C库
  • 只有RTOS
  • 没有在线调试

差不多,就这样子,那种连轮子都要自己发明一遍的平台。

而我写的引擎本身只包括一些基本的功能:

  • 基于C语言的对象系统,支持单继承
  • 场景管理
  • 场景节点树
  • Actions (cocos-2d 那种)
  • 纯软件的2D贴图引擎(支持颜色特效alpha/tint)
  • 动画显示
  • 简单GUI
  • 声音系统接口
  • 文件系统接口
  • Lua配置文件读取
  • 可在PC运行

引擎里面不包括:

  • 物理引擎
  • 线程接口
  • 网络通信

可以看出其实我的游戏引擎并不复杂,总共写下来也就2.3万行C代码。

此外还有数个支持的SDK:

  • 动画格式、编辑工具、编译工具 (能找到不同幀中的相同部分)
  • 高效的压缩图片格式
  • 高效的压缩包格式、打包工具、引擎中的统一用文件接口访问
  • 基于Premake的自动化系统 (类似现在的cocos-2d-x 3.x的cocos工具)

好吧,背景就这些,下面切入正题。

我是如重复发明轮子的

这里只说说我的游戏引擎历程吧。

GML——只能算是API库

从我第一份工作开始的时候,先写了一个射击游戏。然后就开始写游戏的API。那个时候参考了 SDL ,了解的基本的系统接口如何封装。如何跨平台,如何写优秀的代码。所以连我的游戏API库的前缀都叫GML,也算是像SDL致敬吧。

ENS——也是API库

接下来接触了J2ME,学习了相应的API。很喜欢它组织动画的方式。

然后自己业余写了一个叫ENS的游戏API库。风格还是 SDL 式的。同时对自己有如下突破:

  • 期间采用了单元测试,(单元测试真的能找出自己代码中的bug)
  • 采用doxygen输出了漂亮的文档

虽然最终没有写过一款采用 ENS 写的游戏,但是这也算是技术宅的自娱自乐吧。那个时候好像还没有 Github 不然一定会把代码放上面吧。

Horizon——终于能算是引擎了

2008年金融危机的时候,加入了朋友的创业团队。然后开始了我的引擎 Horizon。并用它开发了数个外包项目。

Horizon 的最初出发点是简单。所以一切都从简单出发。但是很快发现它的不足。于是开始接触cocos2d(注意,不是其模仿者iphone版后者C++版),我一下子被它的简洁和使用方便迷住了。印象最深的是他的Action和场景栈。

于是我开始了horizon2,功能就包括了前面讲的那些方面。其中最费力气的,就是动画工具了,因为是嵌入式环境,存储空间小、绘图效率低,所以要尽量找出不同动画帧之间的相同部分,然后分块重用。

此外,还参考了的游戏引擎有 cocos2d-x love2d

其实,也看出来了,实际上要写一款游戏引擎,重要的是找到一款类似的引擎来参考(好吧,就是抄)。

当然其实如果条件允许,还是不要像我这样重复发明轮子的好。我是无奈,因为要运行的目标硬件和系统太差了,不得不重新发明轮子。

另外的学习

其实,开源游戏引擎一大把,无论你是要向我一样发明轮子,还是你想很好的学习和使用一个游戏引擎。这后面需要对很多方面的只是进行学习和了解。比如我觉得最重要的,就是面向对象技术、设计模式等设计和架构方面的知识。

比如Unity3d,如果你使用它,就需要了解组件(Component)模式,这样就能理解其背后的原理。

要了解这些东西,网上有不少资源。比如:

当然上面列的资料只是凤毛麟角,如果你只能记住一条,那么记住 Google 吧。很难想象,一个优秀的程序员,不会翻墙 Google 。

总结

如果你真的要写一款游戏引擎,以我的愚见,你需要:

  • 学习其他引擎是怎么做的,而且了解作者为什么要那样做
  • 学习软件架构方面的知识
  • 翻墙 Google