ios教程,用pc开发ios游戏

news/2024/11/17 23:48:03/

原文是Thomas Henshell对手机游戏Catch the Monkey的开发总结,由Lyra翻译。

传智播客今年6月开始ios培训(http://ios.itcast.cn)的课程;相对于一些应用,我本人对ios游戏开发更感兴趣,这些开发总结并不拘泥于技术,更多的探讨了开发过程。过程很重要,过程正确才能保证结果正确,没有正确的过程,一切方法都是纸上谈兵。

听听Thomas Henshell的总结:

许多人都想做游戏,特别是移动游戏。好吧,我们是你们中的一员。本文就是为想进入这个行业自己动手做游戏的朋友们写的。我们的目标有两个:

1、告诉你这是可能的。

2、分享一些经验教训,或许能够帮助到你。

我们这个叫Mirthwerx的团队其实只有两人:Thomas是自学成材的程序员,Alex则是毕业于Sheridan学院传统动漫专业的美术师。我们是高中同学,20年前就认识,从那会儿开始便试着一起开发游戏。

在着手这个项目之前,我在微软干了15年,写一些web和移动终端的商业软件。因为有这样的背景,我们知道怎么样才能妥善地开发软件[面向对象的编程(OOP)、设计规格、易用性考量]。但后面你会看到,心里明白和实际做到是两码事。

策划和原型

技术

从第一天,我们就知道自己想要两个东西:

1、安卓是未来,但iPhone是当下。两个版本我们都会开发。

2、我们想用windows平台上我们熟悉的环境和工具来做开发。

我买了台mac-mini来研究Mac平台和XCode。用了一天ObjectiveC后,我知道自己一点儿也不想用这种语言来工作,它会把我逼疯的。幸运的是,我们可以用一个办法同时解决这两个问题:Marmalade让使用者能在Visual Studio C++里写代码,却可以在任何平台运行(包括iOS,安卓,黑莓,Windows Phone,Bada和其他平台)。模拟器很棒,想要的性能监控应有尽有。对于独立开发者来说,价格也很合适。

策划

考虑到这是我们的第一个项目,我们想让app的设计简单些。最初的概念是这样的:农场里有些猴子,玩家划动手指来挠它们痒痒。每过一关,猴子会来得更快更多。就这么简单。

在那时,它看起来太容易不过了,因为就俩人,我们觉得没必要做什么开发规范。我们用了Xmind来画思维导图,并把“策划案”放在那上面。这个游戏最初美术的工作量比较大,所以我们的美术就全职扑到项目上,而我只在下班和周末的时候抽点时间捣鼓一下。

原型

在商业软件开发里,最初的原型对用户来说至关重要。它把对文字描述的揣摩和猜测都撇尽了。

我们并没有真的去做个原型,而是用了GameMaker 8,一个很强大却不算贵的游戏制作工具。它让我们可以把画好的图形和一些玩法机制凑到一起,来看看是不是已经弄出点好玩的东西来了。我估计我们的首个原型总共就花了20小时。因为它是在windows屏幕上跑的,所以没法测试真实的触摸/划动机制,于是我们就借助点击,每次点击模拟一个指划动作。这样,最大的问题就变成了:它好玩么?

不,不好玩。我们改了一些数值(猴子的速度、戳戳它们让它们发笑,一次来多少个猴子),但还是太简单了。能做的事情太少,连2分钟都玩不到。我们不是要做一个“搞笑游戏”,所以又重头开始。

头脑风暴过程中,我们想到了一个用不同工具让猴子们动作的主意。挠痒痒是最初级的工具,一根羽毛,后来你能得到其它工具。这下看起来有点儿戏了。我们于是构思了一些工具类型,删减到方便放到原型里去的几种,然后做了第二个原型。在这个版本中,玩家有了一个仓库来储藏各种工具。当一种用完时,农夫可以叫他太太来装满,每次装满之间要隔几分钟。这让玩家会去考虑什么时候用哪种工具。我们也把对农夫的控制交给玩家,他们可以指挥农夫到特定区域把猴子抱回来。最后我们还加入了捕捉星星的概念。每过一段时间,会跳出星星来,玩家需要通过点击来捕捉它。星星后面对升级会有用,尽管我们从来没有把它放到原型里去过。那么:这下它好玩了么?

是,也不是。似乎已经有了一个好玩的内核,但一些迷障始终把它困在里头。我们知道选择工具(作为策略)很好玩,捕捉星星(它是自然产生的,不同于核心玩法,并且很难)也很有意思。我们去掉了农夫的控制权(太费劲),和补充工具的概念(太复杂也太随意)。我们需要一个让玩家能制定策略和管理资源的游戏机制。

必须指出的是,做原型的时候,我们不只是闭门造车,而是听取了项目以外其他人的诚恳意见。自己在项目中的太容易对测试的结果心存偏见了。你们后面就会看到我们是怎么在这上面载跟头的。

小结

在这个阶段,我们成天坐在那里进行头脑风暴。在最后想到《魔兽世界》里的魔法值/冷却机制前,我们有过许多点子。《魔兽世界》里,玩家不能随心所欲地释放魔法,他们有一个魔法条,限定在短时间内能用的魔法值。但有些魔法实在太强大了,如果它们消耗光了魔法条,你就必须等很长一段时间来冷却,所以大招没法在一场战役里反复用。我们觉得,如果每个工具要求一个公共的能量池但冷却时间不同的话,或许能实现我们一直追求的战略平衡。有足够的变数,我们就能让玩家保持新鲜感和乐趣,这样他们就能乐在其中了。

另外我们又添加了一项星星能量的概念。原本星星只是用来升级的货币,现在星星能量可以让你花一定的星星就能使用技能。让星星具有两种功能,就是要让玩家做出决策:当下受益还是留待以后。这是个很棒的机制,我们想应用到别的地方去。作为开发者,要把星星能量设计得真的很有用是一项有趣的挑战,事实上,聪明的玩家只是保守地拿它们来升级。

策划阶段基本完成后(策划其实无处不在),我们进入到核心的开发阶段。


核心开发

简介

在第一部分中,我们介绍了Catch the Monkey从最初简单的概念,到技术选择,直至原型的过程。到原型完成时,我们已经有了一个进步很大的策划案。但因为没有经验,当时并没有把它们完整地记录下来。我们知道有12个工具要开发,有10种不同的猴子,和对商店的不甚清晰的想法。我们想让商店的购买可以升级,但到底多少级,以及升级后能干嘛在那时都还不确定。该动手写代码了!

我们要不要做?!

正如上文提过,美术同学全职扑在这个项目上,而我作为程序员却还要干点儿别的,只能兼职写代码。项目于是被拖累了,最后到了因为没有进度项目要被砍掉的地步。所以,我计算了一下继续做这个游戏需要的时间。6周(50小时x6=300小时)貌似够了。我做了个艰难的决定:申请了6周的休假,回到自己的小屋子,专心一意搞这个游戏。我太太并没有大惊小怪,她支持我把游戏完成。是时候“全力以赴”了。回过头去看,继续项目的选择是对的。

最大的失误

没有一个合适的策划文档看起来成了我们最大的失误。我只做了个非常简陋的文本。

如果你研究过《植物大战僵尸》会发现它有很多类型的僵尸,但他们是由几个图形(头、身体、胳膊、腿)和一些可选的饰物(假肢、头盔、报纸)组成的。如果把这些部件重新组合的话,你可以得到很多不同类型的僵尸,而只需要很小的存储空间。我们想要一个类似的做法来画猴子,使它们拥有各自的能力和缺陷。

然而后来我们痛苦地认识到,如果你想要做到这种重复利用的话,其实需要为每个角色写下来非常周详的规则,哪些它们能做哪些不能。请注意,在《植物大战僵尸》里,僵尸永远面朝摄像机(就好像2D的《南方公园》动画)。无论做什么,它们都不会转过去给你看一个侧脸。

可早在我们制作动画和原型的时候,我们就已经定下来,当一只猴子到达植物时,是一屁股栽下来的,转过去,开始挖掘。当它挖到土豆后,又会转身开始吃土豆。发现这个问题之前,我们已经完成了所有普通猴子的美术工作工。当我们想做一个戴帽子的猴子时,以为只要做一个单独的帽子把它按在猴子头上就可以了。我们开动了。真的完成后,我们发现,如果猴子从摄像机镜头前转身,帽子(或者背心,或者太阳镜)也得跟着转。这就要求每个猴子帧必须对应一个饰物帧以及像素精调,意味着每一帧都要大量苦哈哈的坐标分析,才能让它看起来比较正常。工作量太大了,我们又不想重画挖掘的动画,所以做了一个实验性的决定:把帽子粘在猴子身上,把普通猴复制到戴帽猴。美术同学就这么干了,如法炮制出另外6种猴子。

这个问题的数学公式如下:

1种猴子有一套行动精灵表(恐惧、愉悦、大笑、走路、攀爬,等等),需要大概20mb的VRAM空间。

7种猴子x 20mb=140mb VRAM

在iPhone 3GS(iPod 3+)上只有约55mbVRAM(15mb的堆阵)以下的才不会崩溃。

我们最初还考虑过iPod Touch 2+的,可它只有30mb的VRAM,所以没可能了。因此我们慌忙调整VRAM,使之符合iPod 3+的要求。我们在下文会更多涉及这部分。

因此,教训是:永远都要在策划阶段就考虑内存要求,得在你写代码之前,而不是事发时,或者干脆事后才发现。我们要早知道猴子转身会带来的后果的话,早就在美术上调转方向了,游戏也不会做得那么辛苦。

可爱的猴子在糟糕的现实世界

我认识的许多商业软件开发者都是能不写多线程解决方案就不写。为什么?因为两条独立线程各自运行带来的竞态条件问题对测试来说将会是个噩梦。一旦软件崩溃,由于存在太多排列组合,你会很难重写,更不用说永久地修补它。

当谈到游戏领域,既然已经决定做即时游戏了,无论如何Update()循环每几个微秒都会执行一遍。没有Windows Forms开发中的那种“阻塞调用”概念。这就是游戏的开发模式,我不打算说这个。

我要谈的是即时游戏和回合制游戏。回合制游戏会等玩家输入,然后做出相应回应;在等待玩家互动时,屏幕上会播放一些东西,比如美化效果之类,但实际的游戏状态不会改变。而在即时游戏系统中,则无论玩家是否有动作,游戏的状态持续在发生变化。

作为我们的首款游戏,本不应该选择即时游戏的。

我们为Catch the Monkey做了大量的工作才使得它在持续变化的环境下不出差错。测试场景数量大概需要回合制游戏的20倍。复制一个场景非常非常困难,甚至到了具体单元程序测试时依然如此。在架构阶段有段时间,我都不确定是不是能让它不再崩溃下去。幸运的是Marmalade有个超级给力的记忆管理工具,我最后还是搞定了(至少我这样认为)。

这个教训叫我们吃够了苦头,所以接下来一个项目必须是回合制的。

对象层级

显然,面向对象的编程好处在于可以先编写点小的、专注的、封闭的对象,然后再提升到更高水平上去。我的目标是创建一个知道如何实例化、移动和自我渲染的对象层级。

在我职业生涯早期并没有做建模。但当有人给我看了Rational Rose,UML和建模以后,我走上了不归路。我总是给自己的代码建个模,就算是没有别人看的个人项目也这样。因为我发现这是在写代码前厘清思路的最好方式。Rational Rose(或者其他合适的建模工具)帮助你在策划的时候想清楚策划的问题。Rational Rose我用了有好几年,但到做自己项目时,我可付不起2,000美元的授权费。幸运的是Open Source社区的StarUML救了我。StarUML是个强大的免费建模工具。它看起来跟Rational Rose一模一样(至少和我2003年时用的最后版本是一样的)。

Posted Image

来看一下分级策划图解。请注意两个基础对象:游戏对象和UI对象,它们都是从图形对象派生出来的。图形对象把所有Marmalade 2D API都封装起来,所以需要编译过才知道到底是一只猴子、一段故事板、还是一个文本对象。

游戏对象是在游戏场景(你玩到的那级)里用到的对象。它管理自身的状态,精灵表,色深计算,比例(基于色深),点击操控,和碰撞检测。所有玩法对象都是从游戏对象派生出来的。UI对象和游戏对象类似,但要轻量化一些,是为非游戏场景设计的,譬如文本、按钮和商店图例或工具选择场景。

设计模式

必要时,我们采用GoF设计模式。例如:

  • 我们用“工厂模式”来设计等级;输入周和日,它就会输出一个格式化的等级对象,还包含了必要的教程。
  • 我们用“图形管理”和“音效管理”两个单例模式来捕捉图像和音效文件。所以尽管每个对象都要对应加载和卸载资源,它们能从这些捕捉中将内存需求最小化。玩家状态(星星数量、目前进程、已完成的教程、已购买的升级)我们也用了一个单例模式。这样玩家进度的序列化和反序列化就变得极其简单。
  • 我们用装饰模式来为所有游戏对象添加图形效果,比如淡入、淡出、闪烁等等。

我最早的困惑之一是如何把全部类型的画面(商店、工具选择、剧情模式、标题画面、选择/菜单画面、游戏模式)放在一起组成一个完美的OOP范例。在查找资料的时候,我从rivermanmedia上找到两篇iPhone游戏开发者写的很棒的文章:

The Scene System(场景系统)

The GUI Stack(图形用户界面堆栈)

我知道此范例不仅可以用在这个游戏上,还可能用于未来所有游戏。

The Scene System一文把游戏分解成一系列场景。我把Catch the Monkey分解成19种,包括场景标题和场景对话框,每一个都由场景共同界面衍生出来,比如:Init(), Update(), Render(), Shutdown()。我创建了场景管理的单例模式,里面包含了场景创建、关闭和切换有关的所有逻辑。这样,谢天谢地我的代码可以对更高一级别在发生什么置之不理。如果想要结束一个场景,开始一个新场景,我就写:

SM->ChangeScene(new SceneShop());

如果想关注新场景,把它放在现有场景之上,我就用:

SM->AddScene(new SceneOptions());

场景管理器知道目前是不是有其他场景在运行,会让它们恰到好处地慢下来,从内存里移除它们的资源,做一个淡出过度,启动新场景。有了这个,即时游戏现在看起来更像是个Windows Form应用了,可以用对话调用对话,剩下麻烦的都让OS自己去解决。

第二个核心的概念是用户图形界面堆栈。用户图形堆栈包含在场景管理器里,正如Windows处理表单和对话框那样复制了“聚焦”的处理方式。通过将场景在堆栈上推送和弹出,我可以控制让哪个场景调用Update() and Render()代码。如果一个场景没有收到Update()命令,它就会被有效地冻结(暂停)住。在纯粹的模式中,最上面的场景是唯一接受了Update()调用的,堆栈中所有其它场景则接收了Render()命令。后来在测试中,我为了提高性能移除了堆栈中每个场景的Render()命令。对于需要背景的画面(比如在游戏画面上出现对话框),我用了一个目前状态的截图,而不论当前的场景是什么。

在2D中使用Marmalade

如前面提到的,我们想用C++在VS2008里同时开发iPhone和安卓平台游戏。Marmalade是3D框架,我们知道我们只是做2D,所以专注于lw2D API。我会着重来讲用Marmalade的2D API做2D动画。

你会看到Marmalade工作环境级别相对较低。它不是GameSalad(一个让做游戏不用写代码的软件,所需要做的仅仅是拖曳到窗口——译者),这是我选择它的理由。我宁愿享受比较低级的API却拥有自由改写的权限,而不愿被局限在框架设计者们规定的能做不能做里面。

Marmalade有一个自定义文档叫MKB,很神。这个文档让用户可以自定义Marmalade程序库,把源代码、资源(音效)、字体和材质组导入项目。

Marmalade有一个资源管理器,允许通过在MKB文档中像下面这样定义来管理图片组(材质组UI.GROUP CIwResGroup { name "UI" shared true useTemplate "image""image_template" "./accountbuttons.png" "./account1.png""./account2.png" "./account3.png" "./black.png" "./bluestarbg.png""./pause.png"

然后你在你的自定义组文档里定义你的全部图片:

UI.GROUP CIwResGroup { name "UI" shared true useTemplate "image""image_template" "./accountbuttons.png" "./account1.png""./account2.png" "./account3.png" "./black.png" "./bluestarbg.png""./pause.png"

在代码里,你可以测试是否资源组都已经加载到内存,用下面两个简单的功能命令加载/卸载它们:
if (IwGetResManager()->GetGroupNamed("farm", IW_RES_PERMIT_NULL_F) != NULL) IwGetResManager()->LoadGroup("farm.group");
或:
IwGetResManager()->DestroyGroup("farm");
通过以下命令行可以用文件名(不加.png后缀)加载图片(并自动上传到OpenGL VRAM):
CIw2DImage* img = Iw2DCreateImageResource(name);
一旦你的内存里有图片了,只需要调用某张图片的绘图例程就可以简单地渲染你想要的图片以及2D矢量单位。
Iw2DDrawImage(img, CIwSVec2(x,y));
Marmalade自动按照你调用的先后顺序将绘图调用排序,你就可以通过首先调用背景绘图来控制分层。在我运行Render()例程之前,我先按照色深(从低到高)检索我的对象,然后按照这个顺序绘制它们。
完成渲染之前,我调用以下两个例程,告诉Marmalade我完工了,可以向全世界展示我的成果了:
Iw2DFinishDrawing(); Iw2DSurfaceShow();
就这样。每帧都调用这些绘图例程,你就捣鼓出了你自己的游戏。

简化精灵序列

这个游戏包含超过4000帧手绘动画,多数都是猴儿们在它们世界里的表情动作。为了管理所有这些图片,我们把它们放进了精灵序列。这里需要考虑两个问题:

  • 精灵序列的尺寸不能超过1024(iPhone不喜欢比这更大的材质,于是Marmalade开始检测这些图片)
  • 精灵序列尺寸需要是2的幂次方(32,64,128,256,512,1024)以用作图形卡。如果不是,图形卡会自动把它们拉伸到2的幂次方。

Photoshop里要做个每一帧都长宽统一的精灵序列可不容易。所以我们找到了一个小窍门,为我们节省了几十个小时:

  • 在Photoshop里把每一帧都存成PNG
  • 在GameMaker里创建一个精灵,把每张PNG拖出来从文档系统里,放进GameMaker去,做成一个动画
  • 从GameMaker里把精灵输出成为一个动画条,是由每一帧图片拼成的水平PNG长幅,顺序则按照每帧的文件名排列。
  • 在动画条上运行我们的自定义精灵序列程序,这个长幅就会拆成一张张长方形PNG图片,它们都是最小的2的幂次方尺寸。

听起来很复杂,但其实我们可以在2分钟以内就完成从png帧的收集到排好的精灵序列。哪怕只考虑创建精灵序列的能力,GameMaker也值得你拥有!

结论

最挑剔的批评会来自谁?听众还是音乐家自己?是音乐家。因为他们知道自己每个弹错的音符,也知道自己平时练习的时候弹得有多好。所以创作者总是对自己的作品既充满偏见又很豁达。在他们的初衷和最后实现的结果之间,隔着一个残酷的现实。我想说,想象中的音乐总是要比实际上的来得甜美。

6周后,我完成了游戏开发,花了大概340小时。我知道自己有偏见,但哪怕在开发过程中把游戏玩了上千次以后,我还是觉得这游戏真的好玩。同时取悦3-5只小猴简直是奇迹。因为我一直呆在自己的小屋里,所以美术同学只能听我说说。在部署之前,除了用我的笔记本,他都没法玩一下。但因为确信我们有一个很好的内核并真心为此骄傲,我们决定开始最艰苦卓绝的战斗:打磨。


平衡与打磨

简介

到这里,我们已经有一个可以玩的游戏了,90%特性已经完成。玩家可以开始一个新游戏,玩过每一级,让所有7种猴子动起来,使用所用10种工具,保存星星,在商店购买28个升级,使用全部4种星星能量,以及保存/继续他们的游戏。我们跟自己宣布特性完成了。如果起初有写过更详细的策划文档的话,我们会意识到,没这回事儿。

最后的10%用了90%的时间

我们不知道建立一个发行商关系需要多久,所以开始把一个早期的原型拿给运营代理看。其中有一个说,游戏内核很好,有AAA游戏的潜质,但还需要做大量润色工作。当时我们觉得这个说法很蠢,认为平衡性教调和其他一些细枝末节的工作大概再2周时间能完成,然后就可以上线了。

这便是游戏和商业软件的极大不同。商业软件的特性完成、所有单元测试完毕后,真的算是已经完成了80-90%的工作。集成测试会发现一些问题,但一般只是开发者和开发规范之间需要解决的误解。即时游戏集成测试占了全部工作量的大约一半,因为这关系到游戏元素各层之间的相互影响和依存性。

移植到设备

到目前为止,游戏只能在Marmalade的PC模拟器上玩。我们对它在真机上的表现(内存或帧率)心里没有底。而且因为美术同学完全没法测试游戏,所以单元测试也颇为受阻。该部署到真机上去了。

苹果对于什么能放到它们设备上去非常谨慎。这有助于减少盗版,但也因此给开发者带了紧箍咒,你不得不签署你的代码,获取设备ids码和证书,才能部署测试到设备上去。

如果你是在mac用XCode(尤其是最新版本)开发,过程就会比较简捷,XCode会帮你料理好。所有的苹果文件都会告诉你用XCode每个步骤该怎么做。而如果你是在PC上开发,就等着麻烦来找你吧。

有两个必须做的事情:1)把你的机器设置成可部署iOS状态,和2)把你的项目设置成iOS发行状态。幸运的是,Marmalage 5.2版本里关于如何创建发行的文件比以往的版本要好得多。它包含了从如何创建证书的示范:上传到苹果,再下载苹果的证书,以及把它放在什么地方。

设置PC的时候,项目必须设置和签署为发行状态。苹果的开发者门户会向应用签发设备许可的UDID。苹果提供一个签署项目用的配置证书。Marmalade有个部署工具,在发布ARM就会出现。你把配置和OS具体选项输进这个工具(它会保存自定义的MKB文档),它就会神奇地帮你搞定IPA,这样你就可以通过iTunes部署到你的iOS设备上去。

前前后后,我大概花了10小时才把游戏弄进我的iPod。这是个极其重要的步骤,因为我们需要触屏来测试手势。

让手势酷起来

如果你还记得的话,我们的策划核心是玩家用手指划动来挠猴子痒痒。几个原型之后,我们需要一些其他工具来区分千篇一律的划来划去。最初对我们产生影响的是GameLoft的游戏“财政大战(Bailout Wars)”。玩家轻点银行家来干掉他们,但你还可以做其他的动作。

我们研究了许多游戏,最后理出下面这个清单:

  • 点了以后长按
  • 水平划动
  • 向下划
  • 向上轻划
  • 画圈(顺时针或逆时针)

我们选择点、水平划动、向下划动和向上轻划。(我们一开始也采用了点后长按,但后来去掉了。)我们为不同工具设计了相应的手势:比如纸袋要放到猴子头上去,所以玩家要把袋子往下划到猴子的脑袋上。

iOS和安卓支持多点触控(最多10点),但我们决定只用一个点。一个触摸点就好像一次点击,为此我们审视了Marmalade里的s3ePointerEvent,用下面的代码行捕捉,放到通用的触摸变化上:

void SingleTouchButtonCB(s3ePointerEvent* event) { g_Touches[0].active = event->m_Pressed != 0; g_Touches[0].x = event->m_x; g_Touches[0].y = event->m_y; g_Touches[0].when = (int32)s3eTimerGetMs(); g_Touches[0].handled = false; }

现在我们知道手指在哪里了,这很好,但你怎么知道是在做一个手势呢?答案是,你得自己来编程。

手指触摸屏幕时,手势开始。从这时开始,在它放开(手指提起)之前必须每隔一定区间就检测一遍目前的触摸点,必须分析其相对于原点的变化、点的进程和终止来确定所做的是什么手势。我用通用工具类别及其子类里的战略模式来实施每个手势识别。

我解释了创建手势的原理,但要让它感觉“顺手”还得做许多优化。一样是简单的左右划动,每个人的手势都会不同,真夸张。有的人只是轻巧地划动10个像素点,而另一些则会霸气地横贯全屏。有人水平地划,而有些人则喜欢对角划。有些人划得太慢,机子记录不下来,有的人又划太快记录不下来(我们发现最“准确”的时间间隔单位是每个点50毫秒)。那天结束后,我们得出了一个非常严格的手势系统,水平划的像素比垂直多不超过20,已经足够宽松了。

把剧情放在最后

Catching the Monkey是一个动作游戏。我们要为玩家的动作设定一些故事背景,当然不需要写个《罪与罚》的小说。最初,我们的故事框架如下:

南非的一个农夫拥有一片土豆田。当他和太太一起坐下来用午餐的时候,有只小猴闯进了田里。他跑过去看住那只猴子,但来的猴子越来越多。最后他赶跑了所有的猴子,回去吃他已经冷掉的午餐。结束。

行了,我们可不是要去获奥斯卡最佳剧本奖的,对于游戏来说这已经可以让我们开始了。所以我们把重心放在游戏开发本身上,然后再回头来看故事剧情。

大错特错!

当需要处理剧情逻辑的时候,我叫我的朋友Rob来帮忙。某个晚上,我们坐下来讨论故事。他开始问一些基础问题,而我却答不上来:


  • 这位农夫同学有钱么?
  • 他跟他老婆的关系好么?
  • 他的行为模式怎样:是没头脑型还是不高兴型?
  • 他们在那儿住多久了


这些问题看起来无聊到死,愚不可及!但事实上它们不是。从研究中我学习到,写小说之前,你得先有个角色。于是Rob和我开始定义角色。

整个游戏过程中,玩家可以不停解锁新工具。怎么来告诉玩家呢?我们决定让农夫的太太“发现”它们,并把工具放到他的工棚里。我们选择连续的对话框来介绍工具。然而你不知道角色的说话习惯就没法写对话(哪怕是抓小猴的简单对话)。所以,写对话之前,我们还真得回答这些无聊的问题。

接下来我们要回答的是两个大问题:

1)猴儿们为什么会来?(为什么现在,而不是一年前或一年后?)

2)玩家阻止了猴儿们以后会怎样(在解决了上一个问题之后)?

那个晚上我们想了很多点子,但每个好点子都会改变游戏走向,或者引入新的角色(比如猴王),而游戏已经进入开发尾声了,我们不可能做这样的改变。我们绝对应该在第一周就开这么个会的!

我们在不改动游戏和添加大量新美术资源的前提下写出了最好的剧情。写作的第一条军规是“写你熟悉的”。最后,我以自己和太太为原型创作了农夫和他太太。赶跑猴子对于农夫而言,开始时很简单,后来却越来越难,成为了他的全部人生。这是我的人生隐喻。当农夫为没玩没了的猴子痛哭时,正是我为没完没了的游戏开发任务抓狂时。而背后,是一位淡定的太太。在她力所能及的地方搭把手,在必要的时候给予鼓励。游戏里的一些对话其实就是我太太说的。游戏里农夫太太外出参加“女生旅行”的时候,其实是现实中我太太跑出去玩了。

当然,对于一个简单的捕猴动作游戏,故事有点复杂了,但我还是把它放在了游戏里。

等级和Game Master

我必须先承认:有时候我实在是很懒。但有时懒惰却是发明之母。

当我们开发第二个原型的时候,每一等级都有自己的脚本了:猴子什么时候从树上掉下来,猴子的类别,一次来多少猴子,大部分都是时间驱动的。这是个典型的动作游戏,就像Capcom的“1942”。每个过关都是这样。

希望文章能给你带来一些帮助。


http://www.ppmy.cn/news/471263.html

相关文章

selenium自动化教程及使用java来爬取数据

目录 一、介绍二、下载浏览器驱动1.获取要下载的驱动版本号2.下载驱动 三、Maven如下四、简单使用五、定位器1.定位器2.说明(1) class name 定位器(2) css selector 定位器(3) id 定位器(4) name 定位器(5) link text 定位器(6) partial link text 定位器(7) tag 定位器(8) xpa…

MySQL存储引擎之Myisam和Innodb总结性梳理

Mysql有两种存储引擎:InnoDB与Myisam,下表是两种引擎的简单对比 MyISAM InnoDB 构成上的区别: 每个MyISAM在磁盘上存储成三个文件。第一个 文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩 展…

Django生成接口文档

当我们使用Django开发Web应用的时候,API接口文档的编写是非常必要的。通常我们会使用Swagger、apidoc等工具来自动生成API文档。本文介绍如何使用Django Rest Framework自动生成接口文档。 安装Django Rest Framework 在项目中安装Django Rest Framework&#xff…

二、Docker安装

学习参考:尚硅谷Docker实战教程、Docker官网、其他优秀博客(参考过的在文章最后列出) 目录 前言一、Docker安装1 确定Centos的版本2 卸载旧版本及前置安装2.1 卸载旧版本2.2 yum安装gcc 3 安装方法4 设置 Docker 的存储库并从中安装(官网推荐安装方法&am…

对C++中的虚函数的说明

在C中,虚函数是对多态性(Polymorphism)的一种支持。当基类指针或引用被用来调用派生类对象的成员函数时,可以通过虚函数来实现动态绑定,即根据运行时类型确定要调用的函数。 下面是使用虚函数的两个典型场景&#xff…

装ubuntu18.04 未发现wifi适配器解决方法

问题 系统安装完之后,在设置>>Wi-Fi中显示:未发现WiFi适配器 替换网卡驱动 打开 软件和更新 >> 附加驱动,看看Broadcom栏里面有没有类似下面图里第二项这样的: 有的话就不用进行下一步了,直接勾选一个…

安装Ubuntu18.04后没有WIFI参数设置图标,无法连接wifi

问题描述: 我的电脑是联想拯救者Y9000P,23年的新机子,Win11系统Wifi使用正常,Ubuntu20.04的Wifi也能正常使用,唯独Ubuntu18.04安装后桌面右上角下拉菜单里没有Wifi设置参数选项,设置里Wi-Fi模块提示找不到…

win10蓝牙已配对安卓手机但连接不上 完美解决方法

win10蓝牙连接手机蓝牙,显示已配对但未连接 完美解决办法。 电脑:惠普暗影精灵台式机win10,版本号21H2 手机:安卓手机 1. win10蓝牙连接不是手机蓝牙基本上是驱动太老了,自带Windows没有更新,下载驱动更新…