大概三个月前,我在试着用几款2D游戏引擎。
第一款是SDL,这是同事推荐给我的一款跨平台的2D游戏引擎。这款引擎评价很高,总的来说是因为它够底层,实现的功能非常基本,又提供了一套平台无关的接口。所以开发人员在此之上可以天马行空的开发。不过我不是那么热衷底层……于是我在写了几个实验性的程序之后放弃了他。呵呵,当时研究它主要是因为自己也在做嵌入式,对跨平台很感兴趣。但是当时看一个老外,好像叫lazyfoo,写的开发教程让我学到了很多游戏开发方面基本的知识。
然后第二款是HGE,它是基于driectX的一款开源2D游戏引擎,也是提供较底层的功能。最核心的大概是它提供基于帧的逻辑和渲染回调,开发人员来实现每帧进行的操作。HGE还提供了一套我觉得非常不好的教程,对于新手是绝对的误导——它的教程里的代码都乱七八糟,感觉就像个C++新手写的代码一样,各种全局变量,各种魔数,各种乱命名,可读性和框架性都较差。(可能也是HGE的开发者为了求简,不过我觉得这个教程可以做的更好。)
这时,我自己做的一套简单的游戏,已经简单的设计好UI接口。于是我用HGE来实现这套接口。
我觉得HGE很恶心的地方就是它基于每帧的回调(当然你可以修改HGE内核来去除这一点,不过将带来更多麻烦,因为HGE很多函数就是基于帧回调机制的。)所以你不能像使用一个Canvas一样来进行实时绘制。于是我在游戏里自己实现了一套消息机制,把整个HGE框架跑在另一个线程中,游戏数据核心线程通过发消息的方式去通知界面更新,或者获取玩家操作。
这是当时自己弄的设计,DirectX or Ddraw改成HGE,后来自己也实现了。
刚开始的时候感觉还好,后来代码稍微上规模的话,就觉得很吃力了。因为我是基于具体游戏功能来封装HGE的接口。在之后又重构了几次,整体架构还算清晰,但是界面和代码之间的耦合度实在太大。最后可以实现一定的界面功能,但是还是太不爽了,所以决定放弃使用HGE。在此总结一下自己的想法,如果要用HGE真正开发一款稍微上规模的游戏,应该怎么做,可能也有很多不正确的地方,欢迎指正。
1. 实现页面栈、控件树
我也不知道该怎么定义这个名称,姑且叫它页面栈和控件树吧,其实就类似于WINDOWS的窗口系统,建立起树状结构的控件系统。对于每一个页面记录各种状态如焦点控件等。并通过栈维护各页面的层次关系。可以从配置文件或者页面脚本载入页面。比如游戏中的主角属性页面、装备页面等,框架都是一定的,使用的一些图片资源什么的也是一定的,应该写成配置文件,直接从文件读入。
2. 在页面树的基础上实现消息路由
消息的路由机制必须实现。
3. 建立资源管理器及配置管理器
专门的资源管理器用来加载和卸载各种图片、特效、音乐资源。同理配置管理器,管理整个HGE的配置。
4. 定义界面文件格式并使用界面文件生成具体画面,同时配套开发界面编辑器
如使用XML来定义具体界面,界面编辑器生成XML。
在1,2,3,4条满足的情况下,再进行具体游戏功能性的接口开发。甚至应该把1,2,3,4这部分抽成 引擎无关、平台无关的中间层,向下提供移植接口,用HGE来port。—— 那么整个游戏界面部分以上应该是高度可移植的。
HGE 的 gui 工具是个好东西,特别是里面的 hgeGUIObject,要多用。说个要注意的点,官网上面貌似都没给详细说明……
hgeGUIObject 的 rect 成员是该控件的操作响应作用域——不是显示的。让一个控件disable只要rect.Set(0,0,0,0)就行了。注意有时控件莫名其妙的不响应鼠标操作了,也可能是这个冲突导致的。这问题曾经让我崩溃的调了半天。。。
总结一下。
HGE完全开源、基于directX,功能较为基础。我觉得很适合个人学习和开发小型游戏,但是如果要做稍微大型的游戏的话,必须将整个UI的调度机制设计、封装好(我觉得这个工作量挺大),然后整以相关的开发工具。
OK,HGE就告一段落。