游戏是一门综合的艺术,作者以铸剑为喻,形象地展示了移动游戏架构的艺术之美。
艺术是人的知识、情感、理想、意念综合心理活动的有机产物,是人们现实生活和精神世界的形象表现。文学可以是艺术,雕塑可以是艺术,音乐可以是艺术,电影可以是艺术……那么游戏呢?
游戏是一门综合的艺术
无论是单机游戏还是网络游戏、PC游戏还是手机游戏,都需经过如图1所示的逐步进化的过程。
图1 游戏研发的流程
任何一款游戏,都有故事情节、人物、场景、音乐和音效等内容,因此其中每一部分内容都需要追求以艺术化的手段,将游戏的意象情景更生动地展现给用户。作为程序员的我们,之前可能只是以为只有策划人员需要通过艺术来表达游戏的内容、测试人员需要带着艺术去欣赏并完善游戏的体验,那么程序员对游戏的架构和艺术之间又是怎么挂上钩的呢?
用程序语言铸造艺术之剑
从古至今,有不少人热衷于铸剑,而铸出的剑是否称得上艺术作品,关键就在于它是否能表达出铸剑人的情感和用心所在。那么对于游戏程序的架构来说,也需要能体现出架构师对游戏的整体架构和每一个模块的把握,以及赋予它们的“神力”;同时,好的架构还将贯穿于游戏开发的整个过程。简单的测试一下,你是否也会遇到以下这些问题呢?
- 感觉游戏框架非常混乱,毫无条理?
- 开发完成后出现大量Bug,并且不知从何下手去解决?
- 出现很多难以重现的致命Bug?
- 添加某个功能或模块非常困难?
- 经过频繁的修改之后, 出现大量冗余代码?
如果出现上述问题,那么说明我们所使用的这把架构之剑并不锋利,可能没有将“力”用在剑刃上吧。这也从另一方面体现出铸剑过程(也就是游戏的架构)的重要性。如果带着这些问题继续锤炼,那么终将铸成一把绝世宝剑。
架构是一个看不到也摸不着的虚幻东西,因此,我们还是结合具体的实例来分析如何将架构艺术化,通过代码来表达架构思想。假设现在有一套策划案,并且美术人员能够为我们准备所需要的资源。
“采矿”是铸剑之根本
有了铸剑的意念,就需要去选择各种高品质的玄铁矿石。同样,对于游戏的架构来说,就需要对游戏的各个功能模块进行分析,针对每个模块需要实现的功能和特殊属性进行抽象,概括出各个模块所需要定义的数据结构和接口以及各模块之间的关系。然后,再根据策划文档整理出适合编写程序的流程图、关系图、结构图等。最后,根据这些文档资料配合游戏的运行环境(比如游戏运行的平台)对实现技术进行需求分析,该分析主要针对功能和性能进行。下面我们以Android和iPhone两大平台为例进行分析。
在Android平台上,从效率的角度考虑,可以选择C/C++作为开发语言、OpenGL|ES作为图形库;从简单方便的角度考虑,可以选择Java作为开发语言、Skia作为图形库。
而在iPhone平台上,从跨平台的角度考虑,可以选择C/C++作为开发语言、OpenGL|ES作为图形库;从开发的难易程度考虑,可以选择Objective-C作为开发语言、Quartz2D作为图形库。这里我们没有考虑3D的特殊问题,如果进行3D游戏开发,必然会选择OpenGL|ES。另外,在iPhone平台上使用Quartz2D作为图形库开发游戏的比较少。
如果要做的是一个跨平台的游戏,我们还需要分析各平台的跨平台能力和特性(包括开发语言、渲染库、资源管理、内存管理等),例如iPhone中内存管理采用了引用计数的机制,那么可以考虑通过C++来实现一个类似的机制,这样就可以保证其他平台也都可以通用该机制。
这里我们也没有刻意地对某个语言和库进行比较,因为它们通常都有各自的优势,需要根据具体的游戏需求进行选择。准备好铸剑的玄铁之后,下一步我们开始铸剑(编写代码)了吗?
“剑范”决定“剑气”
“剑范”即铸剑所用的模型,“剑气”即剑品的气势,因此,铸剑所用的模型将最终决定宝剑的“主题”。
“剑范”的打造对应于游戏架构中负责全局范围的核心框架,该框架是否合理,将决定整个架构的成败。说到框架,不得不说说大家可能都比较熟悉的MVC框架,作为程序员,应该没有谁不知道MVC的定义,但是关键在于如何从更深层次去学习它,理解它,运行它。曾经一位朋友问我:“你们通常采用什么框架?什么框架会比较好呢?”我回答:“MVC框架啊!”看着他一脸吃惊的表情和一句“也很普通的框架!”的回答,我真不知道说什么好!MVC框架的确很普通,也很简单,而如何让它发挥出其本身的功效却是关键!例如,在iPhone开发中,苹果公司就推荐采用该框架,具体描述如下:
- 视图(V):由UIView类的子类及其相关的UIView-Controller类来提供;
- 控制器(C):控制器行为通过主要由委托、目标操作、通知来实现;
- 模型(M):通过数据库和数据含义等协议提供逻辑模型,由控制器进行管理。
另外,就连目前红遍整个互联网的Android系统来说,Google官方也同样推荐使用MVC框架来开发和维护应用程序,具体描述如下:
- 视图(V):由View和SurfaceView(或者自定义的视图)提供用户的界面,采用XML格式进行布局;
- 控制器(C):由Activity来管理视图和逻辑模型;
- 模型(M):向视图提供逻辑模型,由控制器来触发,比如各种Adapter接口。
根据切身的经历,我得出了下面的观点: “如果不能保证将其他的设计模式运用好,就不如选择类似于MVC这类的简约而不简单的框架来完成,可能结果会更精彩!”
由此可见游戏架构中框架的重要性。如果你还觉得不够,那么我建议应该向众多的Android和iPhone开发者询问答案,苹果和 Google的文档将是你最好的学习资料!相信你已经跟着我们的脚步,打造出了适合你自己的 “剑范”了,现在是时候开始铸剑了!
真金不怕火炼
宝剑品质的好坏在于使用的原材料,如何检验矿石的材质?还得看准备的火力是否强劲。现在让我们回到游戏架构的话题。
首先,尽管通常游戏中可能会存在多个视图、多个模型甚至多个控制器,我们还是将一款游戏分为三个大的模块,即MVC的控制器、视图、逻辑模型。图2为我当前正在开发的一款Android游戏的框架。
由图2可以看出,程序从入口Activity进入,通过setContentView()函数设置显示一个视图类MainView时,游戏的主线程已经开始Loop了;而游戏要显示的具体场景则由控制器Control类根据游戏状态等信息通过getCurScene()函数得到,得到的场景实际上是抽象场景SceneInterface类的子类(如SceneA);在SceneInterface中包括各个场景的公共接口,以便在Control.control()中能直接控制当前显示的场景,需要注意的是,在控制器中一般需要先通过SceneInterface.reCycle()来对上一个界面产生的垃圾进行回收,同时对逻辑模型类Model中的数据进行处理。
图2 MVC游戏框架
由于图片大小的原因,我没有列出全部类结构,这些类包括在SceneInterface中定义一个界面事件的公共接口或者对Model采用“实体—对象—类”的方式进行扩展以及所需的工具类。
铸剑的最高境界—指导练剑之人
好的宝剑通常可以提高用剑之人的剑术!Google和苹果所铸造的Android、iPhone这两把宝剑,指导了无数的开发者。我们又何不学习学习Google和苹果这两位铸剑人的技艺呢?
下面继续分析Android可能会如何指导“练剑人”。在做Android应用开发时,Google推荐通过XML文件来布局界面,从而让UI界面和程序逻辑分离,方便维护;实际上Google对XML文件以及其他资源都进行了优化,这样做可以提高程序的运行效率。下面我们也将学习这一招,通过XML文件来布局游戏场景。
首先,将一个游戏场景(SceneA)中需要显示的内容分为UI界面(如按钮、菜单等)和游戏对象(如精灵)两部分;其次,UI界面和游戏对象可能都需要动画;最后,既然要使用XML文件来布局,就需要一个专门的解析器。稍作整理,现在我们所需要的模块如图3所示。
图3描述了一个场景的元素架构与解析,其中UI界面、游戏对象、动画模块都将使用一个或多个XML文件来完成,通过XML的解析,最终将XML文件的内容输出到SceneA中。整个过程首先需要构建一个XML解析器,然后根据游戏的需要构建各种UI控件、游戏对象、动画等类。目前工程中用到的类包括:
- UI控件:UIText、UIProgress、UITexture、UIList、UIClick、UICheckBox
- 游戏对象:GameObj、EffectObj、Bullet、Enemy
- 游戏动画:PosAnimation、ColorAnima-tion、FrameAnimation
每一个类中都有其所需要的成员变量,下面我们可以根据解析器的实现来使用XML文件布局游戏场景了。根据游戏的需要,可以将XML文件扩展到支持多级子节点,然后在游戏中获取XML中定义的元素,进行操作即可。同样需要将界面和程序进行分析,方便修改和维护。整个过程的完整流程如图4所示。
实际上我正在进行的项目除封装了上面所说的三个模块外,还将整个游戏架构都进行了封装,包括图2中所展示的控制器、主线程、模型,整个框架都能通过XML文件直接编写。到这里,你所铸造的宝剑也应该出世了,带上宝剑,冲向游戏世界吧。
作者:杨丰盛,轻灵数码研发部经理,精通Java、C/C++等语言及J2ME、BREW、MTK、Android、iPhone等平台。曾领导和参与《三国群英传》、《大航海传奇》等游戏的开发。著有《Android应用开发揭秘》。
(本文来自《程序员》杂志11年01期,转自:http://www.programmer.com.cn/5223/)