开发者分享iPhone游戏引擎编写经验(1)

2014-07-31  来源:本站原创  分类:编程  人气:3 

引言

这次我要谈论的是我的业余项目,即编写iPhone游戏引擎,这个项目从去年8月开始,由2位美工配合进行。虽然项目尚未完成,但这里我想要分享几点自己从中学到的东西。首先先来看看若干游戏截屏:

开发者分享iPhone游戏引擎编写经验(1)

和船只战斗

开发者分享iPhone游戏引擎编写经验(1)

探索游戏世界

在这款游戏中,玩家通过控制船只探索游戏世界,发现新城市,同其他船只进行战斗。玩家还可以在游戏的进程中改变船只的模式。下文我将谈论我在此小型引擎中所运用的技巧,主要包括如下内容:

—内存管理

—工具(Maya插件和关卡编辑器)

—脚本处理(Lua)

—串流机制

— 声音(音效和背景音乐)

—运行调试

下面是几幅游戏截图及我目前所开发的工具:

开发者分享iPhone游戏引擎编写经验(1)

游戏轮廓

开发者分享iPhone游戏引擎编写经验(1)

编辑器

开发者分享iPhone游戏引擎编写经验(1)

关卡编辑器

开发者分享iPhone游戏引擎编写经验(1)

Mac版本

内存管理

在iPhone平台,内存是非常重要的资源。若处理不当,应用就会收到1-2个内存警告,然后你的应用就会被系统终止。所以我决定编写自己的内存配置器,预先分配大部分内存,这样我的应用就不会在运行时被操作系统终止,它可以选择运行或不运行。这是我首次编写内存配置器,它没像“准备、设定、分配”过程那么精细,但足以应对我的项目。

在我的小型引擎中,pool配置器主要用于分配内存,其存预先设定容量大小,从8、16、32及64字节到1048546字节不等。由于我的目标平台是iPhone,而极限容量104854字节通常只运用至若干高分辨率的纹理中,因此我的游戏的多数内存都集中在较小的容量规格。在程序运行期间,很多内存都已形成,它们被分成如下更小的模块以适应各pool规格:

开发者分享iPhone游戏引擎编写经验(1)

memory Layout(from 1.bp.blogspot)

注意,大型字节模块通常位于较小内存空间,旨在实现字节对齐。而各模块则被进一步划分成同等大小的区块,以配合特定的容量配置:

开发者分享iPhone游戏引擎编写经验(1)

memory 8 byte(from 3.bp.blogspot)

各模块中的内存区块保持呈现链接表模式,这样当pool配置器需要分配/归还内存时,它只需返回列表中的自由内存区块/将其添加回链接表中。各内存区块中的内存主要用于储存指示链接表下个自由内存区块的“下个指示器”,这样我们就不需要通过分配额外内存追踪链接表:

开发者分享iPhone游戏引擎编写经验(1)

memory Linked List(from 1.bp.blogspot)

在进行分配时,配置器需要根据配置容量决定所要运用的pool模块。然后在此模块中,自由内存区块就会被送回,这只是模块链接表的顶部。在解除配置过程中,将内存分解成不同模块后,我们就能够把握各pool模块的边界地址,所以通过查看解除配置指示器的地址,我们就能够决定其属于哪个pool模块,然后我们就能够将内存送回模块的自由内存模块链接表。此方式的一个缺点是它无法验证解除配置指示器是否真正由用户配置,以及其是否双倍释放。想要“部分”克服此问题,我需要添加极限检查,以检验解除配置过程的输入内容。首先,我会检验输入内容的字节是否对齐,例如若解除配置指示器处于1048546字节模块中,那么指示器地址就必须和1048546字节对齐。其次,在分割内存模块的过程中,我们将获悉各内存模块存在多少内存区块,我们可以保留一个当前自由区块的数量(游戏邦注:这会随着分配和解除分配而或增或减)。若程序结束后,免费区块数量不符区块总数量,那么内存也许就被遗漏或被双倍释放。但这只能够解决部分问题。

为真正解决此问题及查看内存遗漏情况,我需要记录各个分配和解除分配操作。原本,在分配过程中,我只需要通过宏指令__FILE__,__LINE__存储返回指示器的地址及各分配操作的位置(源文件和行编号)。但这无法追踪所有内存遗漏情况,因为有些文件已被模版化,例如Bullet Physics存储库中的btAlignedAllocator.h。运用宏指令__FILE__,__LINE__只能够记录这些头文件的分配情况,这无法协助我们进行内存漏洞追踪。因此,我还通过system call backtrace()和backtrace_symbols()记录各分配过程的调用栈。然后我就能够轻松追逐所有内存遗漏情况。但记录各分配过程是个缓慢的过程,这只能够在调试版本中实现。

总之,我的内存配置器还有很多需要改善的地方,例如检验用户解除分配过程;在内存区块中添加元数据(游戏邦注:例如配置规模)。出于线程安全性考虑,我目前通过互斥量保护内存,未来我也许会转向无锁版本。尽管存在这些缺点,但这个配置器的运作情况还是颇令人满意,它让我们不会再收到iOS的内存警告,让项目不再出现内存碎片问题,同时还协助我们追踪内存漏洞情况。

Maya工具

工具在游戏制作中非常重要,特别是在合作伙伴不懂如何编写代码的情况下。在我的项目中,我的合作伙伴是两位美工,所以我得编写某些工具,将他们的模型输出到我的引擎中。输出模型有不同的方式,你可以选择解析.obj文件的格式,通过FBX SDK阅读.fbx文件,或是阅读COLLADA文件,但我选择直接从美工采用的模型包中提取内容(游戏邦注:编写Maya插件提取模型数据)。

要给输出模型编写Maya插件,我们首先得弄清数据在Maya中的存储方式。通常Maya会将多数数据存储在Directed Acyclic Graphic(DAG)。在我的项目中,我需要找出这些存储网络数据(mesh data)的DAG节点位置。我们可以按照如下方式通过迭代器MItDag访问DAG:

  1. MStatus status;
  2. MItDag dagIter( MItDag::kDepthFirst, MFn::kInvalid, &status );
  3. MDagPathArray meshPath; // store the DAG nodes that contains mesh
  4. for ( ; !dagIter.isDone(); dagIter.next())
  5. {
  6. MDagPath dagPath;
  7. status = dagIter.getPath( dagPath );
  8. if ( status )
  9. {
  10. MFnDagNode dagNode( dagPath, &status );
  11. // Filter out the DAG nodes that do not contain mesh
  12. if ( dagNode.isIntermediateObject()) continue;
  13. if ( !dagPath.hasFn( MFn::kMesh )) continue;
  14. if ( dagPath.hasFn( MFn::kTransform )) continue;
  15. meshPath.append(dagPath);
  16. }
  17. }

然后我们可以按照如下方式通过MFnMesh获得DAG中的网络数据:

  1. for(int i=0; i< meshPath.length(); ++i)
  2. {
  3. MDagPath dagPath= meshPath[i];
  4. MFnMesh fnMesh( dagPath );
  5. MPointArray meshPoints;// store the position of vertices
  6. fnMesh.getPoints( meshPoints, MSpace::kWorld );
  7. // get more mesh data such as normals, UV…
  8. }

想要获得更多细节内容,不妨参考《MAYA API How-To》和《Maya Exporter Factfile》。得到网络数据后,你就可以通过创建MPxFileTranslator的子类输出这些内容,取代函数writer()。

我选择编写插件而不是解析.fbx/COLLADA的另一原因和提取动画数据有关。在我的项目中,我只需要输出若干嵌入关键图框之间的简单动画数据,我想要获得美工基于Maya定义的关键图画。我尝试运用FBX SDK,但在输出动画数据时,它会将所有动画图像都聚集成关键帧。通过COLLADA所获得的结果则更加糟糕,我无法在Mac平台找到适合Maya的输出装置。而编写Maya插件能够消除所有这些问题,获得我想要的数据。我要编写一个脚本文件,帮助美工设定动画剪辑数据:

开发者分享iPhone游戏引擎编写经验(1)

maya Anim Clip from altdevblogaday.com

输出网络数据后,我觉得在Maya中编辑触碰几何图形是个很不错的主意,所以我编写另一插件定义模型的触碰形状:

开发者分享iPhone游戏引擎编写经验(1)

maya Physics Exporter from altdevblogaday.com

插件的运作方式和Dynamica Plugin非常相似(游戏邦注:但作者的插件只是基于球体、盒子和胶囊图形定义出简单形状)。我的插件无法在Maya中进行物理仿真,它只能够定义触碰形状。这些触碰形状只是MPxLocatorNode的子类,它推翻draw()方式,通过调用openGL渲染出内容的对应形状。

总之,直接从Maya中提取网络数据并不困难。我们可以获得所有数据,例如顶点法线、UV集合和关键帧数据,无需担心基于其他格式输出内容会导致的数据丢失情况。Maya还提供获得这些数据的便捷API,这非常容易掌握。熟悉Maya API后,我还可以编写另一插件定义触碰形状。下次当你需要输出网络数据时,你也许会考虑直接从模型包中提取相关内容,而不是解析一个文件格式。

游戏邦注:原文发布于2011年7-8月,文章叙述以当时为背景。

相关文章
  • 开发者分享iPhone游戏引擎编写经验(1) 2014-07-31

    引言 这次我要谈论的是我的业余项目,即编写iPhone游戏引擎,这个项目从去年8月开始,由2位美工配合进行.虽然项目尚未完成,但这里我想要分享几点自己从中学到的东西.首先先来看看若干游戏截屏: 和船只战斗 探索游戏世界 在这款游戏中,玩家通过控制船只探索游戏世界,发现新城市,同其他船只进行战斗.玩家还可以在游戏的进程中改变船只的模式.下文我将谈论我在此小型引擎中所运用的技巧,主要包括如下内容: -内存管理 -工具(Maya插件和关卡编辑器) -脚本处理(Lua) -串流机制 - 声音(音效和背景

  • iPhone游戏引擎编写之项目事后分析(4) 2014-02-03

    简介 使用本系列文章所描写的iPhone游戏引擎开发的首款游戏是<Monster Bowling>,它已经在圣诞前发布于App Store.(点击此处阅读文章第一.二.三部分) Monster Bowling(from altdevblogaday) 你可能会好奇为何成品游戏与早前呈现的游戏截图(游戏邦注:即玩家需要控制着一艘船去探索世界的冒险游戏)不一样.因为之前参与该项目的人员失去了最初的创作激情,并退出了项目开发.但我不希望自己投入努力而创造出的引擎白白浪费(即未能基于该引擎创造游戏),

  • iPhone游戏引擎编写之脚本处理和流动传输(2) 2014-07-28

    脚本处理 在引擎中添加脚本支持能够带来诸多好处,如无需耗费大量时间重新编译引擎源代码就可以进行游戏玩法代码的编写,还能够在游戏代码和引擎代码间划定清晰的界线.我选择运用Lua语言(游戏邦注:版本编号是5.1.4),因为它易于整合且所占空间较小.我并不擅于使用Lua语言,所以我想在下文中阐述如何将Lua和C/C++捆绑起来.(文章第一部分详见此处) 从Lua处调用C函数 首先,你需要通过lua_open()创建lua_State*(游戏邦注:如果你需要将内存分配器与Lua衔接起来的话,可以使用lu

  • iPhone游戏引擎编写之音频和性能(3) 2014-08-08

    简介 每一款游戏都应该拥有一个音频系统.在我自己的引擎中共有两种类型的声音:3D音效和背景音乐(BGM).之所以区分了这两种声音类型是因为我们能够在硬件上解码BGM.使用iOS上的音频序列(Audio Queue)便能在一个简单的项目中播放BGM.(点击此处阅读文章第一.第二.第四部分) 音效 通过使用OpenAL(与OpenGL类似的一种API)能够播放出音效.引擎中有一个音频线程,所有的OpenAL声音都是通过这条线呈现出来,并且它将通过指令缓冲区(与图形编程中的缓冲区类似)与主线联系在一起

  • iphone游戏引擎介绍 - [iPhone开发入门] 2011-05-17

    近听闻不少08的同学都选择了游戏这个主题,于是不少人在为选择游戏引擎苦恼.于是根据自己的经验写这片博,希望能够给绝望中的同学提供一丝光亮. 说到游戏,说难也难,说简单也简单,想必大家经过了c++这门课程的大项目之后应该有所了解.难就难在需要花心思去设计,对媒体设计的依赖程度极大,所在这里给大家的忠告是 一旦决定了做游戏,就赶紧去找一个媒体设计高手,如果找到这样一个人,你的成功就完成了一半:游戏简单就简单在,只要设计好了(游戏策略和媒体),不像应用程序那样,通常有很多比较恶心的核心技术难关要去突破

  • 开发者分享Android游戏的市场营销经验 2015-05-03

    经过几个月(甚至是几年)的努力,你的游戏终于能够问世,并且来自世界各地的上百万名玩家也将一睹你的游戏风采了.但是我们也都知道,如果想让游戏真的取得瞩目的成绩,革命尚未成功!我们还需要想办法向全世界推广我们的作品! 我已经在两款Android游戏--<疯狂射击>和<ErnCon>中实践了这一过程,所以我将从市场营销角度分享我的相关经验. 我在2009年使用Pascal语言编写了桌面单机游戏<疯狂射击>.那时候刚好碰上第二届Android开发者挑战赛.因为我本身的职业就是一

  • 横跨2D与3D!专属C#开发者的超强游戏引擎Paradox 2014-09-19

    Paradox是日本Silicon Studio公司推出的一款开源的全新游戏开发引擎,能够让你使用C#编程语言来构建出符合心意的跨平台游戏,支持iOS.Android和Windows Phone等平台,代码已托管至Github上.其中的Game Studio能够很好的帮你管理所有的游戏资源,实时的展现游戏编写中的改变,它与Visual Studio的无缝集成,为开发者提供了一个舒适的开发环境,对智能感知编码的使用让开发游戏脚本变得更容易. 无论你的游戏是纯粹的2D渲染.还是2D和3D混合,亦或是

  • 开发者分享自身游戏开发的10个预期目标 2014-04-13

    在担任游戏新闻工作者8年及兼职从事游戏开发2年后,我对游戏产生明确想法:我喜欢它们.我还发现为什么我喜欢游戏及有时排斥它们的原因,还有就是我真正注重的方面. 我的游戏<Gunpoint>的制作已进展到一定阶段,让我清楚自己能够做到哪些方面.但我在此依然是新手.很多内容都是我在开发过程中发现的,<Gunpoint>本身并没有体现这些内容.所以这是个使命宣言:这让我能够详细了解我希望在游戏中实现什么目标,及计划如何实现. 1. 我希望制作带来杰出体验的游戏. 很多主流游戏将自己形容为&

  • 列举独立开发者适用的数种游戏引擎 2015-04-08

    人们时常想要自行制作游戏,也经常会有人组建起小团队,讨论新游戏的制作.多数情况下,有不少团队程序员决定自行制作游戏引擎.我个人认为,任何游戏项目的参与者都应当考虑他们的目标.如果真得是为了制作游戏,那么就没必要费心费力重新制作游戏引擎.目前有大量的游戏引擎可供使用,让开发者开发游戏项目的过程变得更为简单.使用现有的游戏引擎能够让项目更为简单,也能更快地完成项目,保持精灵的合理运转.而且,使用现有游戏引擎几乎可以确保不出现重大漏洞,让游戏可以流畅地运行. 3D游戏开发引擎 Unity3D 3.1

  • 开发者谈游戏引擎及控制方式 2014-08-04

    自从iOS及苹果触屏设备问世以来,许多手机应用开发者都认为在主机上的控制方式并不适用于触屏设备.但捷克工作室Madfinger Games却反其道而行,瞄准那些希望随时随地体验主机游戏的用户. 不只是Madfinger抱有这种想法,Unreal Engine 3开发商Epic Games也是这方面的倡导者,并持续向主机.PC和手机应用开发者提供3D游戏引擎的授权,其子公司Chair Entertainment则已利用该引擎先行推出了iOS大作<无尽之剑>. Madfinter最新游戏<S

  • 为什么没有好用的Android游戏引擎? 2011-02-21

    随着Android平台的不断发展,近期Android开发者数量呈现出上升势头,就连以往较为冷门的游戏开发领域也涌现出不少生力军.然而,全新的问题正摆在了初学者面前,很多他们从未遇过的问题开始浮上台面. "找了好久也没看见合适的引擎,看来Android真的不适合游戏开发"."我试过几个游戏引擎,感觉都不是很好,效率低.BUG不可控","怎么中国就 没人能做个向Cocos2d那样的引擎呢?看来还得等老外做好才能跟进啊."这并不是虚妄之谈,而是一些刚刚

  • 开发者分享首次制作iPhone游戏的5点收获 2013-10-06

    过去几周我都处于沉寂状态,忙于自己首款iPhone游戏的收尾工作--现在我回来了,因为游戏最终入驻App Store平台. 这款游戏的名称是<Math Ninja>,是首款iPhone教育游戏,旨在将加减乘除运算变得更有趣. Math Ninja from macworld.com 在这个过程中,我学到很多关于游戏开发的经验,我觉得你应该会对此感兴趣. 1. 进行重写不要紧 我首次编写<Math Ninja>时,游戏的代码非常糟糕.应该说是糟糕透了.我是Cocos2D新手,所以犯了

  • 10个步骤:如何成为iPhone游戏开发者 2012-09-27

    10个步骤:如何成为iPhone游戏开发者 译者:darrenest Neil Ferguson,是iPhone 游戏「病毒攻击 | Virus Strike」的开发者.在这篇文章里分享了他自己独立开发一款iPhone游戏的经验和感受. 虽然是一名「老」程序员,目前在伦敦从事全职软件创业公司的Neil Ferguson,觉得开发一款成功的iOS 游戏也许并不需要你有太多的程序开发和编程经验. 对编程算是零基础的我,也一直有过想法在业余的时间学习下开发. 我们来看看,Neil Ferguson 总

  • 开发者分享开发iOS游戏的经历与挑战 2014-04-07

    自App Store于2008年诞生以来,我便已经开始制作iPhone游戏.2009年夏天,随着iOS 3.0的发布,如<Eliminate Pro>等游戏开始通过苹果IAP系统推出微交易系统,并且游戏的侧重点也从原先的获取关注转变为争取用户留存率. 2009年末我创造了游戏<Crash for Cash>.这款游戏获取了较大的关注,并多次占据了App Store排行榜第一的位置,共获得了超过100万的下载量.除此之外,这款游戏的广告收益也不容小觑:但是因为它专注于获取更多玩家的关

  • 开发者分享制作的经验教训 2014-07-11

    发行<The Codex of Alchemical Engineering>不久后,这是款关于建造能够创造和改变炼金化合物的机器的Flash游戏,我开始思考化学主题的续作.由于<Codex>已是简化版分子键合内容,扩充至化学元素多半会带来更多机制(例如原子之间的多种化学键)和谜题(不同化合物,从水之类的简单元素到苯之类的复杂元素).尽管如此,但立即制作续集不是我的风格,所以我将此想法暂搁一旁,继续向前迈进. 约1年之后,我拜访了西雅图的油库公园,深受其被遗弃的化学处理管道的启发.

  • 独立开发者分享面向WP7的游戏开发经历 2014-09-20

    距离<Brickbat>首次在Windows Phone Marketplace问世已经3个多月了(游戏邦注:<Brickbat>是作者个人独立工作室Jeffalisk所开发的第一款游戏).在这整个过程中我真心体验到了各种合理与不合理之处,并将在此与其他开发者分享我的相关经验. 合理之处 学到很多 最终,你会发现你真的从自己的第一个项目中受益匪浅(特别当你白手起家开发第一款游戏时).也许对于开发一款仿制Breakout(打砖块题材)的手机游戏来说,九个月有点过长了:但是你要知道在这

  • 开发者谈如何制作首款iPhone游戏 2015-02-02

    在情况好的时候,Simon Read一天可以通过自己的iOS热作<New Star Soccer>赚得约5000英镑.在上周的Develop Conference大会,New Star Games创始人谦虚地将自己在App Store的杰出表现归功于运气,但许多开发社区似乎全然无视Read所述的观点,Hello Games的Sean Murray及Relentless Software主管Andrew Eades谈及iPhone开发的欢乐与艰辛.这里我们将罗列他们关于如何开发首款iPhone游

  • 开发者分享如何创造一款优秀的iOS游戏 2014-02-14

    创造出<Temple Run>的夫妻团队在高峰时期每天能够获得"好几万"美元的收益:<新星足球>开发者Simon Read也一度攀上每天收益5千英镑的好成绩.这些成功的案例都暗示着,对于充满抱负的游戏开发者来说,App Store是最容易且最赚钱的营销平台.我们邀请了<Warhammer Quest>开发工作室Rodeo Games的成员以及<Greedy Bankers>独立开发者Alistair Aitcheson与我们分享创造iOS

  • PopCap分享iOS游戏运营经验 2015-02-05

    我们此前曾有幸同PopCap的Giordano Bruno Contestabile进行交谈,主要关于公司最近宣布计划将其热门作品<宝石迷阵闪电战>拆分成独立的跨平台iOS&Facebook游戏(游戏邦注:此游戏之前是App Store<宝石迷阵2>的一个游戏模式,是Facebook的独立作品). 通过这一举措,<闪电战>将转而采用免费模式,Contestabile还提及虽然自己是这款作品的业务经理,但他很不会玩<宝石迷阵>,他在GDC详述游戏的转变

  • iPhone游戏开发者:iPad将带来更多游戏体验 2014-04-07

    美国科技博客Silicon Alley Insider作者丹·弗洛梅尔(Dan Frommer)周一撰文称,部分iPhone游戏开发者透露,苹果平板电脑iPad屏幕更多,并拥有更多多点触摸输入(multi-touch input),因此将会带给游戏玩家更多的体验.游戏开发者表示,与iPhone游戏平台相比,iPad的大屏幕能够带来更多游戏体验.一位游戏开发者透露,iPad将支持11项多点触摸输入,这意味着游戏玩家可以同时用十个手指和鼻子来控制iPad. 当然,iPad游戏本身也会存有一些限制,如