我是怎么开车的
介绍 desitka 开发的前前后后
最后更新 2014.2.9
引言
其实这篇文章跟开车一点关系都没有,事实上我也根本不会开车。这篇文章介绍的是 desitka 开发从最开始想法到最后实现的整个过程。虽然最终游戏本身不太灵,但我觉得整个过程还是挺有意思的,希望能对看到这篇文章的同学有些帮助。
开始
夏天结束后,我决定要写个游戏。原因有几方面,比如干了很久的活想写些自己的东西,比如之前做了几次48小时的项目想在比较宽松的情况下再试试。
设定
在开始动手前,我记得自己有几个预想的条件:
-
在一周内搞定。
在我看来截止时间是要完成一个计划的最重要的一个部分。像这种业余项目没有压力很容易就会拖着拖着 最后拖到没有兴趣,然后就没有了。现在回头看看这的却是个很重要的决定。 -
要试试用 NME。
很早就看到了这个项目,它通过 Haxe 这个跟 AS3 非常像的语言,将一个和 Flash API 非常 类似的多媒体库实现到了 iOS 和安卓,同时还是能很完美的输出 Flash 版本。我觉得这个项目真是 棒极了,所以这次一定要用用试试。 -
要做个方块游戏。
不知为什么我非常清晰的记得我高中的时候第一个关于游戏的点子,就是要做个超级加强版的 Zooo。(我们一般的叫法就是叫动物管理员,正好跟美版名称 Zoo Keeper 对上了,现在 iOS 上的版本也是叫这个) 在高中的时候我会把 GBA 带去上学,然后班上同学会轮流拿着刷 Zooo 的最高分。这么多年来 Zooo 还是会坚挺的做到每个新的主机平台上。我后面会仔细讲讲为什么我认为 Zooo 是这类"三消"游戏中最棒的。
确定了这些后我就开始动手了 :)
游戏设计!
讲起来"设计"这么高端,其实只是要定下来游戏要是做成怎么个玩法。之前说要做成方块类的游戏,其实是因为我对方块类的游戏可以说是情有独钟。从 Zooo 开始我就一直关注各种各样的方块类游戏。
Zoooooooooooo!!!!
你知道 Zooo 和来自 PopCap 的更出名的宝石迷阵 Bejeweled 之间(除了动物和宝石之外)的区别吗?
在 Bejeweled 里你将三个方块连成了一列或者一行,然后它们就被消去,接着新的方块落下来。如果碰巧又有新的方块连成三个一起那么它们也会被消去并形成连锁。但是在方块消去,其他方块下落的过程中,在 Bejeweled 里你是不能做别的操作的,同时这一过程也比较快,一阵消去和落下后你又可以找别的可以消去的地方了。
但是在 Zooo 里面,在方块消去和新的方块下落的过程中你是可以进行操作的!这样的话你可以在消去一组以后马上找到另外一组进行消去。而且在整个"棋盘"稳定下来之前你进行的消去都是计算在连锁里的,分数也会成倍的增长。这个小小的区别使得 Zooo 里技巧的重要性超过了运气。在 Zooo 里面经过了前期几个等级以后难度会突然飙升,每级的时间限制变得非常段,而且单次消去回复的时间非常少。这个设计的意义就是让玩家要主动去寻找连锁的机会,再下落的间隙找到机会继续连锁。
如果你之前没有发现这个区别那你现在可以赶紧再去找个 Zooo 玩一下。在后期时间急速减少的情况下,冷静的找到几个连锁再依次一起消去的感觉不是一般的刺激。我相信也是这个成功的设定让这个系列能一直重复做下去。
其他有趣的方块游戏
Zooo 的这个连锁的概念在 iOS 上一个挺出名的游戏 Smiles 更是做到了极致。里面明确的有 "floating time" 的设定,你可以轻易的进行上十次的连锁。
我还有印象的一个方块游戏就是 NDS 上的陨石大战 Meteos。这个也是典型的看起来一般般玩过的都说好的一个游戏。你要用将方块连成一行或者一列然后他们会向上"发射"出去。被发射的方块不是一瞬间就飞起来,你还可以将单个的方块弹上去组成新的排列进行二次发射,可以再下面发射新的方块将上面的顶起来等等。总之是一个紧张刺激的方块游戏。
另外一个游戏 BLOCKSUM。一般的方块游戏里只有颜色作为区别,BLOCKSUM 里引入了数字,并且成功的运用数字设计了一个独特的规则。值得一提的是这好像还是一个同人游戏,游戏的教程里也有很带感的摇杆操作示意图。
说起来容易做起来难
看着别人做的东西说几句的却很轻松,轮到自己做的时候感觉真是... 糟糕极了。最初的想法基本上是"我要做一个有方块有数字的游戏"。接下来在纸上一直画各种数字,过了一段时间有了个简单的想法。
MATH MACHINE FTW!
如图所示,大概的意思就是棋盘上布满了数字,右边有一列运算符。要轮流的使用数字和运算符来取得尽可能大的数字。很快的我就觉得将运算符也放在棋盘上,然后只允许使用邻近的格子来组成算式会比较靠谱。我记得当时我是觉得这个想法挺好的,具体来说有几个有意思的地方:
- 可以加入一些高端的运算符如开根号,指数取模。
- 加入负数,这样和一些特定的运算符配合会有很好的效果。
- 不寻求组成更大的数字,而是寻求组成特定的一个数字。这样就有点像算24点。
我很开心的定下来名字叫 MathMachine (这个名字最后在安卓版发布的包裹里还是看的到),然后就开始动手写了。但是很快我就开始觉得这个想法稍微有点不靠谱。具体的来说也有几点:
- 运算符的顺序,比如乘法和加法应该怎么做,或者是否加入括号?
- 数学算式的显示。要显示漂亮的数学算式自己写好像不太来得及,而且 NME 貌似没有相关功能。
- 游戏的技巧在哪里,怎么想都觉得很难做出需要技巧的地方。
- 感觉机制太复杂,节奏很难快起来。
想到这些问题我又忧郁了。在为这个问题纠结了一天半以后,我决定先到处找些游戏找找灵感。
Remix!
m-flo 的一张专辑里有一段很傻的采样大概是这个意思 - "有人曾经说过,现在你已经不可能创造新的东西了。世界本身已经饱和了。你所做的事只是记录它。但是如果(怎么怎么的),你就可以 Remix The Present!"。于是我就开始四处寻找灵感了,其实也只是到处找类似的游戏玩,看看能不能找到什么想法。
我有时候看到有意思的游戏或者站点都会稍微记录一下。在 Kongregate 逛过一圈了以后,我在 nekogames 找到了这个游戏 - PLUPON。
游戏的规则非常简单,每个关卡中带有数字的球会不停的落下,你要将三个组合起来让他们加起来是10,从而让他们消去。如果加起来的和不是10,那么他们会合并到一起,数字会变为它们和处于十的余数。举个例子的话,比如选择的是 2 5 3
那么它们就消除了。如果是 8 7 4
那么加起来是 19
, 最后会剩下一个 9
的球。目标就是达到几次消去。虽说这么简单,PLUPON 本身做的非常精致,而且关卡之间变化挺大,让人很容易继续玩下去。很自然的,我就想到把这个核心的规则套用到方块游戏上。最终 desitka 也是在这个基本的规则上构造的。
最终设计
基本上按照上面的思路,在棋盘中连续选择三个临近的方块,之后如果和是10的倍数则直接消去,这种情况下面称为消除,如果不是则最后一个选取的方块值被替换为和取10的模,称为替换。为了增大可以消去的可能,我决定不要求三个方块是在一条线上,只要下一个方块是在当前方块的周围8个方块内即可。因为在确定游戏规则上已经花费了太多时间,后来就草草的决定实现两个模式。
一个是最后的 Puzzle Mode,也就是像 Zooo 一样的不断消去且不断有新的方块补全的模式。之前提到了我非常喜欢 Zooo 中的连锁,于是在这里我也想办法加上了一个连锁的模式。在三个方块被选定且确定消除后,它们不会立即消失而是会有一定的等待时间。如果在期间能在它们相邻的地方旁边继续找到一组可以消除的方块,那么两组会连起来最后一起消去,同时分数也会有增加。同时这样的设计也使得替换的规则看起来有了意义,即你可以通过替换来调整一些方块的数值最后达到大规模的连锁消除。
对于时间限制,我最开始是觉得做成像 Zooo 那样不断地减少,消除方块会进行回复的会比较有意思,后来出于两方面考虑没有这样做:一是具体的递减时间需要花很多时间调整才会有感觉,另一方面我是觉得这里需要多留些时间给玩家来组织连锁。所以最后采取的方式是每局游戏固定3分钟的时间。
游戏最终还有一个模式 Zen Mode,这里方块的数量是固定的,也没有时间限制,消除并不会使得方块消失。大概的意思是通过已有的方块尽可能的使分数最大化。说实话这个模式做的非常随意,基本上是因为感觉可以做就做上去了。事实上我对益智游戏中的 Zen 模式都不是很喜欢,所以自己做起来也很没有想法...
事实上整个模式的设定在开发过程中是有在不断调整的。所以我觉得很多时候没想法也没关系,基本的思路定下来可以先慢慢做到一个基本能玩的程度,过程中十有八九就会有新的点子。
到这里整个游机制就戏基本定下来了,关于这方面的总结我会在最后详细讲讲。接下来就是实现上的技术问题啦。
实现
Haxe 和 NME (OpenFL)
Haxe 它号称是一个没有平台的语言。它本身是一个跟 ActionScript 3 和传统的 C#,Java 非常类似的一个语言。之所以说它没有平台是因为 Haxe 可以直接编译到 C++,C#, JS 和 Flash 虚拟机上。最理想的情况下你只要会用 Haxe 那这几个平台都可以一次搞定。NME 则是在 Haxe 的基础上的一个像 SDL 一样的多媒体库,使用 NME 的话你可以直接生成 Flash, iOS和安卓等平台上能够运行的程序。
像这种新的技术看起来总是感觉非常棒的,但真的怎样还是得用过以后才能有结论。就我的经验来说 NME 的却达到了他所宣传的东西。NME 首先给人一个感觉就是很整洁,不像很多库下下来你需要复制粘贴然后跑脚本怎么的才能新建一个项目,NME 提供了一个安装包,下下来后再装上 FlashDevelop 就能开始用了。NME 编译到 Flash, HTML 和 Windows桌面的选择只需要选一下然后再 IDE 里点运行就可以了。在我准备发布到手机的时候我想估计会非常麻烦,令我意外的是用 NME 基本上只要指定一下 Android SDK,把手机连上电脑,然后直接命令行里运行一下就搞定了。Haxe 本身有一套基于 XML 的 build 系统,使用 NME 也能通过这个系统来完成一些细节的配置,比如额外的添加 Java 代码处理安卓的返回键等等。
NME 本身是按照 Flash 的 API 来做的,基本上就是按照原来的 API 重新实现了一次,你可以想象它还是缺少很多不太常用的 Flash 的功能,但要做一个简单的小游戏还是非常足够了。开发过程中我基本上是一直在电脑上测试的,等大体都做完了我才试着在手机上跑,结果是出乎意料的顺利,基本上没遇到什么问题。最后生成的 Android APK 本身只有 2mb 左右,但是安装后大概会占用 20mb 左右的手机空间。这好像是所有使用 NDK 的安卓程序的通病。就效率上来讲可以明显的看出手机上还是没有 Flash 版本那么流畅,但差的也不是太多。而且 NME 相对于其他跨平台方案,在很多评测里都有很好的数据。其他的方面,NME 的开发也是一直在进行中,不断有新版本发布,配套文档也很棒。
讲了这么多好像都是优点,NME 还是有不少欠缺的地方的。首先是不支持 Unicode,这对中文用户就是一个很蛋疼的问题。然后就是没有配套的 UI 解决方案,现在的话基本上只能靠你手动做一些简单的 UI。(2013.2月: 在3.5.4版本后支持了 Unicode 显示,输入我没试过。现在 UI 也有很初步的解决方案了。)
(2014.2月:NME 现在改名为 OpenFL。功能上基本没有变化但是感觉要成熟了一点,去年很火的 Papers, Please 就是用的这个,所以现在应该算已经有成熟商业作品了。)
偷懒的办法
自己一个人写游戏的好处是所有方面都可以自己掌控,坏处也是所有事情都要自己做。比方说图像和界面也都是很头疼的问题。我有几个常用的偷懒方法,还是觉得挺有效率的。
我相信很多人都有在配色上头疼的经历。最简单的黑白灰色当然可以,但是碰到要自己挑选些颜色的时候往往很快就不行了。幸好现在有很资源提供很多非常棒的配色方案。比如有 Adobe Kuler,这边是面向 Web 开发者提供配色方案,但很多场合也非常适用。再有就赞到飞起来的 ColourLovers。它真的是一个非常有爱的网站。首先这边可以给所有的颜色取名字,现在几乎所有的颜色都有个非常文艺的名字。然后网站还提供了一系列制作配色方案和 Pattern 图像的工具。之后就是来自用户的各种各样的配色和图案啦。desitka 最后使用的是这两个配色混合在一起 1, 2。
颜色定下来了,还需要一个背景图片。这里我用的是这个很 Web 2.0 的 StripeGenerator,再加上一个循环的缓慢移动的效果,看上还真去很有益智游戏的感觉。
我一直觉得好好挑选一个字体也是能对整个游戏看起来的效果有很大的提升,特别是在美术资源很缺乏的情况下。这里我使用的是 Lato。打最后整个游戏看起来的样子就是这样:
我觉得看起来还是挺不错的。除此之外,我还用 Ableton Live 做了些简单的音效。熟练使用任意一个音频处理软件都非常划算,要做出听起来还过的去的声音比起要画出看起来还过的去的图,我觉得要是容易多了...
关于代码
仔细想想我之前写过的还基本都是平台动作。这次坐下来感觉还是差别挺大的。
首先这次的游戏是没有一个 Main Loop 的!准确的说其实是没有一个显示的主 Update 函数这样。我之前一直都很忽视各种 Tween 的库,这次用了下 NME 自带的 Actuate,发现如果这种用好了的话可以省掉很多事情。
Flash 有着很多各种各样的 Tween Library,这种一般作用就是你可以通过一次调用来设定某个物体今后的运动和动作,并且可以设定在动作结束时的回调,等等。如果你用过 jQuery 的话你面的 show/hide/animate 就可以看做是 Tweener。当然一般 Tween Library 自己都会有一个总的 Update 来管理状态,但比让自己手动管理是要方便了很多。但我觉得能够完全用 Tween 来解决也是因为这次的游戏类型决定的。总而言之,Tween 的却是很方便的一个工具,不光在 Flash 里有,其他很多环境中也有类似的东西。
对于多分辨率的适应我这做的非常简单,基本上是按 Flash 版本设定一个大小,然后如果是其他分辨率按比例缩放。UI 元素基本都是居中后调整下大小。说实话 Android 多分辨率这个我还没有看到什么特别简单靠谱的办法。
顺带的游戏的代码在这里。基本上你只要安装好NME设置好 Flex SDK 的位置就可以跑起来了。
最后只好躺下来
到最后游戏还是很顺利的做完了。我发布了一个Flash版到 Kongregate,在好基友的帮助下弄了个 Google Play 的账号发布到了 Android 市场上。Kongregate 上的版本很快就有了评论。我一直觉得 Kongregate 上有一批高端用户会不断的查看新发布的游戏,并且很认真的给出评价和评分。然后安卓版本到现在为止,除了我之外另外还有一个用户下载了!很想认识一下到底是哪位好心人。
游戏做出来后我就放到手机上,偶尔在坐地铁的时候还会刷一下。总体的感觉就是 ... 挺没意思的。连我自己都很难坚持玩完一整局,而 Zen 模式简直是碰都不想碰一下。总结下来,我觉得总体失败的原因大概是以下几点:
-
最突出的一个失败的设计就是之前提到的"替换"操作,就是加起来没有到10的情况下,消去两个格子的情况。一方面这使得刚刚接触游戏的玩家很难掌握规则,他可能会不断地尝试尝试消去方块,发现有时候会消去一些,有时候又会停住。我觉得这种情况就是缺少了一个"非法"的情况,就是玩家只要任意选取三个相邻的格子,他的行为都是会产生效果而且是正向的效果的。虽然用分数做了区分,但这样显然是不太合理的。另外一个方面,设计"替换"操作的最初目的是为了让玩家可以通过预先替换来为大规模的连锁做准备。结果在实际游戏中我自己就发现这个是很困难的... 这也归结到下面一个问题
-
游戏的具体情况跟预先设想差别很大。整个游戏做起来以后我才发现,按照这样的设计其实是要找到满足"消去"条件的格子还是挺难的,绝大多数情况下还是靠运气,而技巧仅仅体现在了是否能尽快的找到这些满足"消去"条件的位置。
-
游戏本身的玩法的却不是那么有意思... 就是这样了,整个机制本身虽然看起来很完整但真的我自己都觉得很没意思。Zen 模式简直就是一个悲剧,回头看看我都不知道为什么要做这个模式。
到这里本文就结束啦。虽然最后结果看起来这么伤感,但对我自己来说还是挺有意义的。我终于自己设计了一个 Puzzle 类的游戏,试过了发布到手机市场。所以说做这种东西在成本不高的情况下基本还是很受用的。以上~