这是意念自己的毕业论文,在一个具体的实践之中,意念主要负责的是物件和GUI之外的其他游戏系统。意念才学疏陋,望众位前辈不吝赐教。由于代码质量不高、环境很难于配置、资源包过大等问题,意念暂先不提供代码和程序,未来有时间的时候组织一下这些曾经的代码,再向外发布。
文过三月,也有些新的想法,以后会慢慢跟大家聊的,欢迎拍砖哦^_^。
关键字与术语:
游戏、 游戏引擎 、高层引擎、规则 、场景、物件、Terrain(地形)、解释器 、Application Framework(应用程序框架)、GUI(Graphics User Interface 图形用户界面)、Manager(在本文中特指管理器)、触发器、
设计模式(Design Patterns)、
Singleton(单件模式,一种设计模式,使某个类在某个程序的生存期内,有且只有一份实例,而且可以在任何时候得到这份实例。)、
Adapter(适配器模式,一种设计模式,将一个类的接口转换成客户希望的另外一个接口)、
Factory(工厂模式,一种设计模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类)、
Thanatos(死本能,代表恨与破坏的力量。死本能投射于外,则表现为求杀的希望,表现为侵犯和仇恨的根源;如死本能外投受挫,则为“自杀倾向”,包括自我谴责,自我惩罚,对敌手的嫉妒和对权威的反抗等。)、
OGRE(Object-Oriented Graphics Rendering Engine)面向对象图形渲染引擎
Abstract:
The abstraction of game engine is an important question in game programming, and the kernel of the question is “How could we give the game engine more adaptability?” In the paper we attempt to deduce the form which our game engine must be from our daily-lives. With the help of OGRE, I completed the game engine which has the form that we have just deduced.
The major questions of this paper are: First, why we make game engine? Second, how we make a game engine? The first question was answered in Part1, while the second in Part3. And the Preview gives us a theoretic conclusion to the second question. At the end of this paper, we used the game engine which has just been completed to make a simple game.
The main idea of the paper is to take game engine as a combination of the high-level game engine and the low-level game engine. We use the high-level game engine to support game logic, and low-level game engine to support device and platform API.
摘要:
游戏引擎和框架的抽象一直是游戏制作中的一个关键问题,其核心问题是如何令抽象好的引擎具有更好的适应性。本文尝试使用演绎法从我们所生活的世界推导出了高层引擎为了适应游戏需要所需要保持的形态,并通过实做利用OGRE完成了满足这个形态的一个简单的高层引擎。
本文的关键问题有两个:一是为什么要有游戏引擎,二是我们怎样来构架一个游戏引擎。在第一部分和第三部分我们分别回答了这个问题,绪论则作为对第二个问题所进行的演绎和推导。在本文的最后,我们利用完成的游戏引擎制作了一个简单的游戏。
游戏引擎应分为为高层的逻辑提供支持和为底层的功能提供封装的两个部分,这是本文的中心论点。
目录
<group id="_x0000_s1123" style="WIDTH: 414pt; HEIGHT: 140.4pt; mso-position-horizontal-relative: char; mso-position-vertical-relative: line" editas="canvas" coordorigin="2354,4407" coordsize="7200,2446"><lock v:ext="edit" aspectratio="t"></lock><shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></path><lock v:ext="edit" aspectratio="t"></lock></shapetype><shape id="_x0000_s1124" style="LEFT: 2354px; WIDTH: 7200px; POSITION: absolute; TOP: 4407px; HEIGHT: 2446px" o:preferrelative="f" type="#_x0000_t75"><fill o:detectmouseclick="t"></fill><path o:extrusionok="t" o:connecttype="none"></path><lock v:ext="edit" text="t"></lock></shape></group>
“游戏是先于人类的,许多学者在关注游戏时候发现,在自然界哺乳类动物里存在着大量的游戏行为……
“尽管游戏的历史是悠远久长的,但人类把它当作一种理论研究对象却是在近代才开始的事。德国诗人和剧作家席勒在研究艺术起源的问题上曾以‘艺术起源于游戏’的大胆一说而语惊四海。他认为,人类在现实生活中要受到精神与物质的双重束缚,在这两种束缚中常常失去了理想和自由,人们就设法用剩余的精神创造一个自由的世界,这个自由的世界就是游戏。”
——《游戏之王·游戏文明论》
<shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m,l,21600r21600,l21600,xe"><stroke joinstyle="miter"></stroke><path gradientshapeok="t" o:connecttype="rect"></path></shapetype><shape id="_x0000_s1125" style="LEFT: 2511px; WIDTH: 6886px; POSITION: absolute; TOP: 4543px; HEIGHT: 2038px" type="#_x0000_t202"><stroke dashstyle="1 1"></stroke><textbox style="mso-next-textbox: #_x0000_s1125"><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-LEFT-COLOR: #d4d0c8; BORDER-BOTTOM-COLOR: #d4d0c8; BORDER-TOP-COLOR: #d4d0c8; BACKGROUND-COLOR: transparent; BORDER-RIGHT-COLOR: #d4d0c8"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 15.4pt; mso-char-indent-count: 1.71"><span style="FONT-SIZE: 9pt; COLOR: gray; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">“游戏是先于人类的,许多学者在关注游戏时候发现,在自然界哺乳类动物里存在着大量的游戏行为……</span><span lang="EN" style="FONT-SIZE: 9pt; COLOR: gray"><p></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 15.4pt; mso-char-indent-count: 1.71"><span style="FONT-SIZE: 9pt; COLOR: gray; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">“尽管游戏的历史是悠远久长的,但人类把它当作一种理论研究对象却是在近代才开始的事。德国诗人和剧作家席勒在研究艺术起源的问题上曾以‘艺术起源于游戏’的大胆一说而语惊四海。他认为,人类在现实生活中要受到精神与物质的双重束缚,在这两种束缚中常常失去了理想和自由,人们就设法用剩余的精神创造一个自由的世界,这个自由的世界就是游戏。”</span><span lang="EN" style="FONT-SIZE: 9pt; COLOR: gray"><p></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: right" align="right"><span style="FONT-SIZE: 9pt; COLOR: gray; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">——《游戏之王·游戏文明论》</span><span lang="EN" style="COLOR: gray"><p></p></span></p> </div> </td> </tr></tbody></table></textbox></shape><wrap type="none"></wrap><anchorlock></anchorlock>
人类对于游戏的研究起源于近代。关于游戏起源的问题,自近代而来就有了多种理论:例如席勒的“本能论”,斯宾塞的“剩余能量论”,谷鲁斯的“练习理论”,弗洛伊德的“宣泄理论”等等。
然而,什么是游戏?游戏的本质是什么呢?我们先看看下面几种游戏形态,看能否获得一些启发。
棋牌似乎是所能列举出的人类最早的纯智力的游戏形态;而当游戏规则开始与体力结合时,就诞生了诸多体育项目;自上世纪60年代之后,伴随着芯片处理能力的提高,又产生了电子游戏这种新的游戏形态。抛开这么多游戏的存在形态不说,精神是物质的映射,游戏这种人类的精神产物所反映的是如何的客观存在呢?
象棋、军旗和围棋,是从人类战争中找到了灵感。战争,是人类所能接触和理解到的事物。
图0-2 象棋很可能来自于人类对战争的理解和认识
现代战略战术类电脑游戏的规则大多始祖于近代出现的军事推演,这个军事推演可以准确的说是从战争中找到的灵感。
图0-3 左:《文明》的截图 右:1894年,清政府派人参加美国军方军事推演时的照片
图0-4 左:《地球帝国》的截图 右:1910年,美国海军军事学院的一场海战推演
图0-5 左:《帝国时代2》的截图 右:近代图版战争游戏的包装盒
最早的电子游戏是1962年在PDP-1型电子计算机上,由一个名叫斯蒂夫·拉塞尔的大学生开发出来的《Space War》,单从名字我们就可以看出这个游戏所立足的,是人类对于空间的幻想,和对于战争的体会。
图0-6 左:在这台电脑上,诞生了人类历史上第一款电子游戏 右:利用计算机绘制的太空幻想图
图0-7 左:战术FPS游戏《CS》 右:提出了Thanatos和Eros的奥地利心理学家弗洛伊德
图0-8 左:传统图版RPG游戏的人物属性表格 右:玩图版RPG能激发玩者丰富的想象力
图0-9 左:某网络RPG游戏场景截图 右:正在玩图版RPG游戏的玩者,右下为裁判
而被冠以“暴力”等罪名的FPS,尤其是万人瞩目的Quake和HalfLife,似乎也是为了满足弗洛伊德所说的人类对于Thanatos的本能追求,其表现形态往往来自于真实的杀戮场面,这些杀戮场面在一些网站、文学、新闻和电视剧中比比皆是。
下面来看看另一种游戏类型——RPG游戏。欧美RPG的始祖是托尔金的名著《指环王》,作为一部文学作品,《指环王》似乎是从人类各个集团的政经军事的交互中寻找到的灵感,同时在这之中体现出了一个幻想的世界和幻想的世界观。此后发展而成的《龙与地下城》规则,更是继承和发扬了这个体系,刻画了一个世界的各个集团之间的政治、经济、哲学和战争的体系。幻想的事物,也作为人类所能接触到的事物,成为了游戏开发者赖以开发游戏的灵感。《龙与地下城》远在电脑游戏出现之前就已经被做成了图版游戏。后来,电脑游戏介入了这个规则体系,用一种崭新的面貌重现着以往的图版游戏中刻板的教条和变化无穷的世界。
由上面的叙述我们可以看到,游戏的开发都离不开“人类所能接触到的事物”,这中间包括人类所能接触到的客观世界和精神(艺术、幻想)世界。《电脑之王·游戏文明论》中说到:“电脑游戏的本质就是模拟现实”,这也是图灵所揭示的计算机的本质特征:“模拟人类的思维”。
游戏既然是对客观世界的认识和理解,那么就可以站在最为抽象的角度,来分解这个认识和理解。
一是远古以来就业已存在的世界:山水、森林……诸如此类,他们有一个共同的特点,是很少或几乎不会因为人类的精神活动而发生变化,基本上可以认为在整个游戏期间很少或没有变化。这一部分我们用一个词语来描绘就是地图或地形。一般在三维中都叫地形,二维中都叫地图。
二是这个世界的居住者以及他们所使用的各种工具:人、动物、汽车……,他们有一个共同特点是会发生强烈的相互影响相互制约的关系。由于变动明显,这一部分的物体经常会发生变动。这一部分我们也用一个词语来描绘就是物件。在另外的分类中,往往也把地图和地形当作一种物件,但在大部分游戏中,这两者属性和方法都不同,因此我们在此将地图独立出来考虑。
第一二世界的组合就成了我们肉体可以感知到的物质世界,而这个世界在我们心灵中的映象,就叫做场景。换句话说,广义的场景就是地形和地形之上的物件的集合。从一个简单的角度来考虑,我们可以把场景看作是舞台布景,舞台背景等等就是地形,而舞台上的演员和一些杂物等等就是物件。
第三世界是一种比较难于感知的世界,它肉眼无法看见,但却在很长的时间期限内处于相对静止状态的规律集合。例如 “生命体失血过多会死亡”、“在其他条件相同的前提下,有效率的人比没效率的人在单位时间内收益要大”,等等等等。这一部分很大的可能会在暗中影响到“第一第二部分的世界”,我们用一个词语来描述它就是规则或者规律。这一部分还有一个重要的内容就是人类精神领域的活动,包括思维世界和情感世界,我们可以把这种活动认为成一种特殊的规则和规律。
游戏作为一种交互娱乐手段,还有一层层面就是交互。交互中首当其冲被大家接受的是通过这个人一切可能的方式来向游戏系统输入,来从游戏系统接收输出。因此I/O控制是一个游戏系统所必须的系统。例如我们下象棋时,我们的手可认为是游戏系统的输入设备,可见的棋盘和棋子从游戏系统向我们发送输出,可认为是游戏系统的输出设备。
另一方面,在电脑游戏中。I/O系统除了键盘鼠标显示器这些基本的设备之外,还有一个交互的重要组分就是GUI界面,对于现在越来越复杂的游戏系统,一个仅通过鼠标和键盘,靠输入命令来维持的I/O是很难想象的。因此GUI用它的强大功能弥补了标准I/O设备的不足,因为GUI系统的重要性,因此在这次我们也必须把它考虑在内。
通过上面的论述我们可以得出的结论是:一个游戏可分解为地图、物件、规则、I/O控制和GUI的集合。作为棋牌类游戏可以考虑之为地图、物件、I/O和GUI部分退化而规则相对进化的游戏,古代没有那样强大的系统来完美体现地图、物件,因此规则就相对强大得多。近代出现的军事推演已经是一种有完整地图、物件和规则的游戏系统了。而作为GUI,似乎只有电子游戏才有这样的东西,它是为了方便交互而产生的。
大部分游戏引擎中,会把第一部分映射为地形(地图)系统来处理,对其支持至少有:地图文件的读取、导出、渲染等。
而第二部分,各个不同游戏的实现也不尽相同,一般引擎对物件的支持除了渲染外,至少会提供如下支持:物件碰撞检测、模型编辑等。
第三部分,这有很大一部分是受游戏类型的限制,而且即便是在相同游戏类型里面,由于程序员的个人划分不一样,也会出现不同的结果。比较基本的技术包括状态机等。
第四部分,GUI和控制则有很多参考,MFC等都是很好的参考,因此这一般不是经常会被拿来讨论的技术。
本文所主要讨论的就是利用一个现有的底层引擎来构架高层引擎,并借之讨论高层引擎构架的一般思路。
曾经有一段时期,游戏开发者关心的只是如何尽量多地开发出新的游戏并把它们推销给玩家。尽管那时的游戏大多简单粗糙,但每款游戏的平均开发周期也要达到8到10个月以上,这一方面是由于技术的原因,另一方面则是因为几乎每款游戏都要从头编写代码,造成了大量的重复劳动。渐渐地,一些有经验的开发者摸索出了一条偷懒的方法,他们借用上一款类似题材的游戏中的部分代码作为新游戏的基本框架,以节省开发时间和开发费用。于是就慢慢产生了游戏引擎。人对于游戏引擎的概念是逐步深入理解的,这个过程类似于其他技术的进步过程——毕竟游戏引擎也是一个程序。这个理解所立足的就是对“封装性”的理解。实际上在引擎这个概念下面更多的是每个人对引擎各自不同的理解:游戏引擎只是一个说法,至今为止没有一个公认的定义。
近几年一部分初学者所理解的引擎是“对底层功能的简单封装”,这个底层功能包括平台API、渲染API、音频API、流媒体API等,这样的引擎往往是一种C语言时代的思路,其划分是来自于各个不同部分之间的“功能”关系,而非“逻辑”关系。经典概念包括:渲染核心、内存管理、骨骼动画、帧动画、文件操作、物理库、网络库等等。这个在广为传诵的网文《游戏引擎剖析》(参考4)里面有最为明确的体系划分:
1、“渲染和构造3D世界,3D环境的光照和纹理”。渲染永远是引擎最具有技术含量的部分,就不说那动辄千百块钱的图形卡了,单是图形渲染相关技术的进步速率,就已经足以让人瞠目结舌了。“什么是渲染器,为什么它又这么重要呢?好吧,如果没有它,你将什么也看不到。它让游戏场景可视化,让玩家/观众可以看见场景,从而让玩家能够根据屏幕上所看到的东西作出适当的决断。”渲染所需的主要底层功能就是来支持OpenGL和DirectX的最新技术。由于这些技术不断更改,导致渲染器的更新换代也相当明显。好在OGRE本身就是一个很巧妙的渲染器,它为我们隐藏了很多渲染器的复杂性,让我们可以用近乎自然语言的方式来进行图形处理。
2、“内存使用,特效和API”。图形研究到高层次就不得不考虑到芯片的一些特性:例如显存和内存管理、Shader和其它重要的参数。这也是属于引擎必须染指的内容。
3、“模型与动画,细节级别LOD”。游戏引擎应该支持常见的模型文件格式并很好地渲染他们,如果游戏引擎需要用到自己的数据格式,那么它需要为几个主要的模型文件格式做导出插件,以满足美工的需要。
4、“物理,运动,效果”。物理系统可以让游戏尽可能地逼真。“作为游戏开发者来说,无论我们做什么,我们需要能够检测墙壁,检测地板,在世界中处理和其他对象的碰撞。这些是现代游戏引擎的必备。”先进的物理系统如ODE,可以在保证效率的前提下精确处理物理和运动学理论和公式,其中甚至包括流体力学。
5、“声音系统,音频APIs”。耳朵也是人的一个重要的感觉和信息获得器官,这一点应该很好理解。
6、“网络和连线游戏环境”。网络游戏必备。如今大多数真正有长久生命力的游戏都至少有一些连线成分。“最纯粹的单人游戏容易玩一次,也许两次,或者甚至三次如果它是非常好的游戏,但一旦游戏结束,就被束之高阁了。如果你想要有任何长久生命力,那么多人连线游戏就是形势的核心所在。”
7、“脚本系统”。你可以把游戏脚本认为是电影脚本,它们两者实质上是相同的。
8、“人工智能和导航”。
当按照这个思路建立了自己的引擎后,我们的引擎只是一个功能引擎,它没有任何逻辑关系。包括场景、地图、物件、规则等一系列游戏逻辑所直接相关的东西,它都没法直接提供。这个时候我们所具有的引擎大约是如同下图所示:
图1-1 基本的的底层引擎核心结构
一种可怕的平铺性的结构,互相之间没有关联或很少关联。也就是说,它基本什么逻辑都没有实现,每一个游戏你可以重用这些底层功能,除此之外,你需要重新写所有逻辑,即便两个游戏在基本逻辑上基本相同。国外的游戏引擎已经可以让你脱离代码,只用脚本和编辑器就可以做游戏了(这种开发手段叫做MOD),这种简单的平铺结构,没有纵深,根本无法架起这样一栋充斥了逻辑的大楼!
我们拿2D地图来做一个例子,在这样的引擎思路下,地图只是诸多图元的拼接、Blt(发音Blit,位图位块传输)和互相遮挡。这个思路确实反映出来了地图的本质,但是对于游戏逻辑来说,它太细了。因为游戏逻辑是不需要管你地图图元如何拼接、Blt和遮挡的。下图左就是针对这种设计思路的,而下图右则是提供了高层引擎的设计思路。通过对比可以发现,右边的设计思路更符合OO的封装原则,而左边的主要是比较古老的过程式填鸭。
图1-2 左边是直接在应用程序里硬编码底层功能,右边是在应用程序和底层引擎之间建立一个抽象层,有这个抽象层划分和承担游戏的基本逻辑。在OO大行其道的今天,你会用哪一种方法?
而在这里我们理解的引擎除了功能元素之外,同时包括一些逻辑意义的部分,即部分开发者交流中所说的“游戏层引擎”或“高层引擎”,为何会存在这部分引擎呢?答案是为了方便我们表达游戏的上层逻辑。底层游戏引擎所立足的都是平台API,是与API严格相关的。目的就是为了要让外界看不见API,专心做外界的逻辑部分,但底层引擎只完成了一个目的就是通过封装API来完成一定功能,封装好的API是否就表明一定适应上层逻辑的要求呢?这根本不可能,因为它不是为了这个目的而存在的,例如骨骼动画和上层逻辑有什么关系呢?因此人们又提出了高层引擎的概念。这就回答了刚刚的问题,骨骼动画是应当包含在物件逻辑内部实现的,对外部应该是透明的。如果游戏逻辑需要细化到“谁谁谁,按照骨骼动作‘Walk2’来行走”,那就太麻烦了,这种情况下,比较普遍的做法是我们由来实现一个物件,然后为其设置一种状态叫做STATE_WALK2,在物件自己的逻辑里面当发现物件是处于这种状态的时候就开始引发“Walk2”动作,这样,最后的游戏逻辑只用简化到说“那个谁,向前方走一步”就可以了。实际的处理是,引擎层获取到了这个消息以后,向物件“谁”发送一个TranslateState(“走”)的消息,而物件“谁”获得这个消息后,根据当前状态自动进行状态机的切换。对于逻辑的开发者来说,这一切都是封装好的,透明的,他们只需要知道“当我说‘A向前走’,A就会向前走”就可以了,这样的引擎就不再简简单单是功能平铺的平房,而是具有一定逻辑保障的大厦了。STATE_WALK2到Walk2的对应关系在不同游戏引擎里面可以通过不同方式实现,最初也是最简单的方法是硬编码(Hard-Code),这种方法速度快,然而牺牲了程序的维护性,会给测试带来很大麻烦。现在,大部分的游戏引擎可以通过配置文件甚至是编辑器来解决此问题,以及与此类似的问题,这种数据驱动的方式使编码逻辑更加简单,同时也使设计者和导演工作更加方便。
下图是我们使用一款外国引擎的编辑器时的场面,在这个编辑器里面,既有物件编辑器,也有场景编辑器,同时也包括脚本——这个编辑器里用它来实现我们所说的规则——的编辑器:
图1-4 看着很像3DMax的一款游戏编辑器,中国目前大部分游戏
工作室还没有自己的实力开发这种高度集成的编辑器
把话题引回来,对比前面我们得出的结论,做一个游戏,实际上就是在做场景(地图+物件)、规则系统、GUI系统和I/O控制系统。那么我们该怎么做呢?构建一个过于集中的,把所有功能都实现了的高层系统,只会降低高层引擎的可适应性,因此属于高层引擎更多的是对它们提供支持,这些支持包括:基本数据结构和组织方式(例如物件链表及查询操作、特殊的文件数据)、工具集等。通过这一层的存在,最高层逻辑只需要写:在场景中放置几只飞鸟,按照Sin函数路线飞行。至于飞鸟飞行中是怎么振翅,怎么偏航,这是在物件系统的具体物件类——这里是飞鸟——里可以决定的。为了最终产品的逻辑需要,我们迫不及待的需要一个“高层游戏引擎”,这是源自于一个很重要的思想,同时也是软件工程的基础思想:“软件产生于需求”。底层引擎层次的划分完全来自于平台和API的限制,因为毕竟我们要做的游戏必须跟某一个平台相关。而高层次的引擎结构则是跟需要达到的目的严格相关的,因为这是它的存在动机。
实际上现在大部分引擎都是或多或少地包括了高层引擎部分的,然而高层引擎的划分却并不容易,大部分引擎所面向的还是FPS这种游戏类型,做一款普遍适应的引擎是难上加难,因为不同游戏所需要的高层不一样。
我们这篇文章的基本目的,就是试验当拥有一个现有的底层引擎的时候,如何构建一个高层引擎,以及如何让这个高层引擎具有更强的适应性。
现在我们具有的引擎构造大抵如下:
图1-4 按照现在的划分诞生的高层引擎层的基本框架