王昌建
摘要:如今的电子游戏风靡世界,无论什么大型的游戏都是基于游戏引擎设计和开发出来的。该文对游戏引擎的各个功能进行了详细的阐述,并使用C++程序设计语言实现了游戏引擎中内存池管理、文件管理、图形控制系统、渲染器、物理系统、媒体系统、输入控制系统等主要功能。
关键词:C++; DirectX;游戏引擎
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2015)27-0064-03
1 游戏引擎概述
1.1 什么是游戏引擎
电子游戏中玩家所体验到的剧情、关卡、美工、音乐、操作等内容都是由游戏的引擎直接控制的,它扮演着中场发动机的角色,把游戏中的所有元素捆绑在一起,在后台指挥它们同时、有序地工作。简单地说,引擎就是用于控制所有游戏功能的主程序,从计算碰撞、物理系统和物体的相对位置,到接受玩家的输入,以及按照正确的音量输出声音等。
1.2 游戏引擎介绍
游戏引擎是负责与系统底层联络的一套程序规范,游戏的效果很大程度取决于游戏引擎的好坏。一款好的游戏引擎所带来的画面冲击感和游戏流畅度,对于一个游戏的生命周期来说是至关重要的。
1.3目前主流游戏引擎简介
CryEngine由德国Crytek开发,主要的游戏产品是《孤岛危机》,《孤岛危机:弹头》,《蓝色火星》等。Gamebryo由Numerical Design Limited与Emergent Game Technologies公司开发,主要的游戏产品是《上古卷轴Ⅳ》,《辐射3》,《魔界2》等。用BigWorld引擎制作的游戏主要有《北斗神拳OL》,《天下2》,《星门世界》,《三国群英传online2》,《传世西游》,《峥嵘天下》,《格兰蒂亚OL》,《鬼吹灯OL》等。此外还有Epic Games公司的Unreal Engine、Criterion Software公司的RenderWare以及开源免费的Ogre引擎等。
2游戏引擎各模块介绍
游戏引擎一般应包含以下系统:渲染引擎(即“渲染器”,含二维图像引擎和三维图像引擎)、物理引擎、碰撞检测系统、音效、脚本引擎、人工智能、网络引擎以及场景管理。
2.1渲染器
在Windows平台下的渲染器主要就是DirectX 3D。DirectX是一种应用程序接口(API),是计算机计算图形的一种规则。它可以让Windows为平台的游戏或多媒体程序获得更高的执行效率,在这个规则中大量包含着现实实例的抽象集合,意味着它具有强大的灵活性和多态性。然而其抽象主要表现在参数的自定义和运算结构的随意组合,但其运算结构的坚固(独特/固定的运算规则)也使其具有很强的稳定性。DirectX加强3D图形和声音效果,并提供设计人员一个共同的硬件驱动标准,让游戏开发者不必为每一品牌的硬件来写不同的驱动程序,也降低用户安装及设置硬件的复杂度。
2.2物理引擎
目前在游戏里被大量普遍应用的物理引擎有两种,分别是Ageia开发的PhysX以及Havok的Havok系列引擎。
PhysX 是原AGEIA公司开发的一套物理运算引擎,主要竞争对手是Havok。同Havok一样,Physx也可运用在Xbox360,Playstation3,PC,Mac等多种平台之上。Physx的另外一个优势是可以运用独立的浮点处理器(包括独立的物理加速卡和GPU)进行更为复杂的运算效果,同时减轻CPU的计算负担。Havok成立于1998年,主要为游戏开发商提供物理仿真技术,从而使对象能够以更加真实的状态展现。
2.3音频引擎
目前主流的音频引擎为FMOD。 声音系统是为游戏开发者准备的革命性音频引擎。采用了FMOD作为音频引擎的游戏包括Far Cry(孤岛惊魂)、Tom Clancy's Ghost Recon(幽灵行动),甚至著名的World Of Warcraft(魔兽争霸)等。
2.4脚本引擎
主流的脚本语言有perl,lua,ruby。游戏中一般使用的脚本语言是lua,因为lua体积小、开源、执行速度快,语法也比较简单。例如魔兽争霸用的脚本就是lua,网游中的任务也一般是lua。
2.5人工智能
人工智能就其本质而言,是对人的思维的信息过程的模拟。人工智能是一门前沿交叉学科,属于自然科学和社会学科的交叉。网游中用到的并不多,一般就应用在怪物发现玩家在附近就主动攻击等场景中,在格斗类游戏中,就是对玩家出招,进行相应的反击操作。
2.6网络引擎
网络引擎主要职责是负责数据传输,保证数据的稳定性。ace是一个比较有名的开源网络通讯库,而且跨平台。
2.7场景管理
场景管理是对数据进行有序的组织和管理。现在的游戏动不动就10G以上,如果没有一个有效的数据管理就不行了,如何在适当时候加载相应资源,一些资源不需要了,就从内存中释放掉,从而能够保证内存空间足够,这是相当重要的。
3基于C++的游戏引擎开发
3.1核心模块:内存池管理系统
内存管理在C++中相当重要,如果内存处理,稍有不慎都有可能导致内存泄漏。而且频繁的申请内存,释放内存,都会造成内存碎片,时间长了可能导致申请内存失败。如果使用内存池,就可以很好的管理内存,更可以有效地减少内存碎片,而且可以有更快的速度申请释放内存。
内存管理方式如图1所示,首先向系统申请一块较大的内存,设置内存块头标志,并存入内存池链表中进行管理,每次向内存池,都先向内存池头中搜索,如果有足夠的空间,就从当前内存池中获取空闲空间,并设置相应地头标记。但是如果空间不够,就创建新的内存池,并存入链表中进行管理。但是如果都用相同级别内存池大小,可能会造成很多的内存浪费,可以创建多个级别内存池,每个级别用不同大小,在申请内存时候,可以根据申请的精度,自动匹配到相应的级别进行搜索获取相应的内存,这样可以减少内存浪费,增加内存池利用率。
3.2核心模块:文件管理系统
商业游戏中用到的图片、声音很少直接赤裸裸的放在文件夹中,不进行任何的打包和加密,一般都有自己的一套文件格式,内部进行压缩加密。如果不进行良好管理,则很难进行维护,而且资源也不安全,可能被别人利用。而一套文件管理,既可以保密自己的资源不被别人利用,而且可以减少了资源占用空间。
文件系统的实现方式如图2所示,首先有个文件系统头信息,里面记录当前文件的信息,包括指向第一个文件夹,第一个文件的信息,通过访问第一个文件夹的头数据,可以继续查询到下一个文件夹信息,指向的文件信息,指向第一个子文件夹信息。访问文件数据头时候,可以取到数据的头信息和数据。使用链表方式管理所有数据,进入可以自由添加删除文件系统内的所有数据。
3.3核心模块:图形控制系统
不相同的2个点构成线,不共线的3个点组成了面。所以面是3D的基本元素。图形系统由场景、资源管理(纹理管理,静态模型管理,动态模型管理,渲染状态管理)、摄像机,地形,天空盒,天空球,静态模型,骨骼动画,纹理贴图,材质,雾化处理,灯光,粒子系统,文字系统等组成。
3.4引擎模块:渲染器
渲染器,是专门针对各个平台的操作系统,而定植的。目前很多游戏都提供了多种渲染器(DirectX,OpenGL,Software),甚至是多种平台(Windows,Linux,mac)。Ogre中,就是将渲染器做成了插件的形式,根据需要,加载DirectX的渲染器,还是加载OpenGL的渲染器,从而可以有更好的适应性。而Software,则是纯软件模拟的,所有的渲染状态,混合处理,坐标转换,全部都自己用算法实现,而不是考DirectX和OpenGL内部已经帮你处理好。
3.5引擎模块:物理系统
物理系统,是一个纯逻辑,算法的模块,内部封装的各种复杂的处理算法,并提供简单的接口,本引擎目前只完成了八叉树碰撞检测系统。游戏中碰撞检测导出可见,若是没有碰撞检测,那玩家变的飞檐走壁,可以横穿各个物体。有了碰撞检测,就能很好地限定在指定允许的范围内行动。在2D小游戏中的方法,简单地用是数组来的碰撞物体,人物行走很,可以简单的跟数组中的值进行判断即可,而在3D中就行不通了,三维游戏中场景特别大,就得用特别是算法来实现了。
3.6引擎模块:媒体系统
游戏中若是一点声音都没用那将是多么枯燥,背景音乐能够体现一个游戏的主题,类型,打斗的场面,会有刀剑的声音。背景音乐用到时高保真音乐,用于播放背景音乐,且不频繁切换,由于加载时间比较长。音效,是使用了硬件缓冲区的接口,能够快速播放音效,缺点是质量不高,但是速度能足够快,一样用于游戏中打斗声音,开门声等。三维音效,像CS中的音效一样,通过判断声音,能够辨别出声音发出的方位,是比较真实的模拟音效。缺点是比较耗资源,运算量比较大,通过多普勒定理算出的。
3.7引擎模块:输入控制系统
游戏都是互动的,不可能全部由计算机执行,而不用玩家参与,用户反馈就显得相当的重要。目前pc机上的输入设备主要有鼠标,键盘。因此鼠标和键盘成了用户与计算机交流的通道。游戏中也是,玩家通过控制鼠标,键盘可以控制游戏中人人物驰骋沙场。Windows系统中的,获取输入消息,可以通过Windows消息队列,也可以用API函数。Windows消息队列缺点是相应的速度不够快(相对于竞技类游戏),API也是一样。dinput就很好地解决了这个问题,dinput直接与硬件打交道,可以直接获取硬件状态。dinput中获取数据状态有2中模式,缓冲模式和即时模式。缓冲模式,是只有当状态发生变化的时候才有消息(如果在短时间发生的多次消息会存到dinput消息队列中),即时模式是获取当前的状态(中间发生的多次消息将被忽略)。一般游戏都会用缓冲模式,应为他获取的值更加准确可靠。
3.8 引擎模块:辅助系统
一般一个引擎都有一套自己的库文件系统,内部自己实现一套数学库,复杂的运算函数,字符处理,等待都是為了扩平台做前提。本文设计的引擎辅助系统,目前仅仅完成几个简单的字符处理,ANSI与Unicode字符转换,自定义的一套类型。
3.9 引擎各模块联系
本文设计的引擎各个部分静态结构图如图3所示。
MdMemory内存池,是本文设计的引擎的核心部分,负责管理内存。其它对象都是通过内存池来获取相应内存,这样保证了所有对象数据都在内存池的管理之中,由内存池进行了统一的管理。内存池在析构时候进行了检测是否发生泄露,并提示在那个文件第几行代码发发生的,并有一个专门的值,可供设置断点使用,在下次启动时候自动中断在泄露的位置,然后通过编译器的调用堆栈查看,可以快速看出问题的所在,大大的简化的各个模块内存使用的情况。文件系统,内部使用了内存池接口,并使用了一套文件夹头,文件头信息缓冲机制,由于采用路径访问方式,要访问子路径中的文件,就必须先访问文件夹信息,通过一个缓冲方式储存在内存池中,比直接从硬盘加载,查询的速度快了很多,而查询缓冲数据,用了哈希算法,快速定位,并有个最长时间未使用的记录,把长时间不使用的信息移除,保证了缓冲的高效使用机制。内部实现了加密算法,保证了数据的安全,杜绝的数据被窃取。图形系统,是包含了所有3D图形的算法,实现,内部封装了各种复杂的实现算法,并提供一套简单的接口,而且和文件系统关联,加载数据可以直接从文件系统获取,避免所使用到的资源裸露在外头。内部对各种资源的头数据进行了扩展,方面图形信息直接使用,而不用计算配置后使用,使之能快速有效。图形系统的渲染接口用了渲染器的接口,在Windows系统下,可以像ogre一样可以自由切换DirectX9或OpenGL来渲染。图形系统中,用到的碰撞检测调用物理系统完成,集合到图形系统的场景管理中,可以无需外部特别的处理,可以方便有效的实现碰撞检测系统。
4 总结
本文介绍了3D游戏引擎的各个组成部分,并使用C++语言实现了一个能够完成基本3D功能的游戏引擎。经过测试,基于该引擎能够开发一些中小型游戏产品,并且该引擎是开源免费的,对理解游戏引擎的原理有一定的作用。
参考文献:
[1] Matt Pharr.Gpu Gems 2:Programming Techniques for High - Performance Graphics and General-Purpose Computation[M].Nvidia,2005.
[2] David H.Eberly.3D Game Engine Design: A Practical Approach to Real-Time Computer Graphics Second Edition[M].北京: 人民邮电出版社,2009.
[3] Jim Adams.Advanced Animation with DirectX[M].Course Technology PTR,2005.