引子
最近,这个折磨我多年的项目终于完成了。现在有种当年高考结束后的那种,空白的感觉。绷着的弦松了,之后是急剧的脱力感。其实还有一些收尾工作要做,但每次打开电脑之后,都是坐着发呆。拖延了一个星期,还是觉得应该写个总结。至少把自己走过的弯路写下来吧。
做独立游戏,我觉得至少应该具备三个条件:
具备能看懂技术文档的英文水平
具备基本的编程能力
具备基本的将想象具像化的能力
但如果你像我开始的时候一样,什么都不会,我会鼓励你保持热情,但我不建议你真的全身心投入进去。如果还是心中躁动不安,无论如何都想尝试的话,我真的希望每一个这么有热忱的人都能成功。所以我写了几条浅薄的建议,至少请你规避我犯过的错误吧。
所以,这应该算是一篇错误经验总结,以下的建议或者犯得错误可能在专业人士眼里不值一哂,但这些东西的确困扰了我很长时间,我希望我的这点建议能够给予像我一样,一无所知而又无知无畏的愣头青们些许帮助吧。
问题之一:目标不明确
其实开始的时候,目的并不是做独立游戏。根本就没敢想。当时只是想做一个demo,好让自己去应聘的时候更得心应手一些。但是做着做着就开始失控。谁说的来着,创作是件非常让人上瘾的事。
开始没多久的一天,我突然意识到这可能是长这么大头一次做自己的东西,做自我表达,那为什么一定要做一个 demo 呢,直接做成游戏的话表达的不是更清楚吗?说干就干,从那天以后项目铺的越来越大,想法也越来越多。潜识里就想把它做好,这个功能想做,那个东西想加进去,再加上那个时候精力无限,从早上一直忙到晚上十点多,饭都能忘了吃。那段时间很过瘾,但也因为那种热血上头的状态,使我忽略了很多问题,为以后的日子埋下了不少隐患。
第一个被忽视的问题就是,目标不明确。
凭着饱满的精神和一腔热血,看似每一天都很忙碌。但倒底要做成什么样,自己并没有想好。在很长一段时间里,我的工作模式都是,突然有个想法感觉不错,然后马上去捣鼓出来的个原型,一会儿又觉得那个创意很好,立刻着手做个功能实现。最后发现积攒下来的东西,前言不搭后语。这些也许可以作为素材以后用,但是做游戏不能这样想到什么做什么。
创意可以天马行空,但程序是一个系统工程。我是后来看罗伯特麦基写的《故事》-第十九章-作家的创造方法才意识到这个错误。之后又推倒重来,浪费了大量时间。
总体而言,成功者和挣扎者之间的区别在于他们相反的工作方法:从里到外和从外到里。挣扎型作家倾向于采用这样的工作方法:他凭空想出一个想法,稍加酝酿,便直奔键盘。 ——罗伯特麦基《故事》
真是当头棒喝。将 demo 改成独立游戏的决定做的太草率了。其实无论在何种状况下,如果打算做独立游戏,还是应该冷静下来,认真考虑一下的。现在回过头来看,更恰当的方式应该是,像大家广泛建议的那样:在开始动手做之前,先完成一个事无巨细的设定文档。比如游戏的核心玩法是什么;要用什么算法实现;是3d还是2d;是横版过关还是第一人称;需要讲故事吗;要讲故事的话是线形叙事还是非线性;需要人物吗;人物动画是帧动画还是骨骼动画……
或者收集脑子里蹦出来的各种画面,比如坐车的时候窗外流动的霓虹灯,进而做出个特效;比如在快餐厅吃饭的时候看到的某个角落的景色,从而做出个场景;最后将这些零零碎碎的东西整理拼凑出个大纲。
这个过程需要的时间可能要比想象中的长的多,但好在这个部分可以在大脑中完成,有些时候只需要纸和笔,而不需要耗费过多的资源。在这个设定完成之前,不建议动手去做,但也不是说这个工程中就不需要写程序了。想法还是需要去通过写程序去验证,看是否能够实现或者效果是不是足够好。
比如,我就曾想在游戏里实现一个画面波动的效果。以下是将这个想法实现的过程,可能会感觉非常冗长:
类似的波动效果
灵感
在网上搜索一番之后,发现最常用的方法是用 OpenGL 自己写一个 shader,然后加进游戏里。但是我对 OpenGL一窍不通,又不想花时间学习,当时就想放弃了。不过在浏览游戏引擎 SpriteKit 类库的时候,发现有一个叫 SKEffectNode 的类,文档中提了一句说可以调用 CIFIlter 类实现某种效果。我又去看 CIFitler 类,这个类好像是 iOS 用来处理图片的,其中有一些 Distortion 的 filter 效果看起来很有趣,也许能用来实现我想要的效果,但是这些都是处理静态图片的,并不能处理动态的东西。
CIBumpDistortion文档说明
前提
实验嘛,那就弄着玩呗。SpriteKit 是先在 ViewController 里设置一个 SKView,然后再通过 SKVIew 的 Scene 属性来设置游戏内容。所以基本上这个 Scene 类就是游戏场景的地基,之后所有的人物啊,物体啊等等就加在这个 Scene 里。文档里有一个提示,说 SKScene 类其实是 SKEffectNode 的子类,所以也就是说如果对 Scene 类像使用 SKEffectNode 类一样操作,比如指定 filter 什么的,理论上是可行的。并且对 Scene 添加效果,那所有添加到 Scene 类的子类都会有相同的效果。
SKScene是SKEffectNode的子类
实施:
- 实际操作之后发现黑屏,而且内存猛增。不好使?
- 看 log 发现实际上方法已经运行了,但不知道为什么没有效果。难道不兼容?官方文档上建议可以使用 CIFilter,应该是没问题的。
- 于是又重新开了一个 hello world 工程,用最简单的方式测试,这次却可以运行了。
- 好吧,最起码证明这个方案是可行的,只是不知道为什么在我的游戏工程里不行。像我这样的凡人,就只能用最笨的方法,一点点的去试,看到底是哪里出了问题。于是我在游戏工程里加了一段跟在测试工程里一模一样的代码,运行之后发现还是不行。
- 唯一不同的是在测试工程里用的是随便找来的图片素材,而游戏工程里是游戏素材。这次又换成测试工程里的图片,运行之后,ok 了。
- 所以是素材的问题,又是一番测试,最后得出结论:想要通过 SKEffectNode 实现效果,整体 Scene 的内容不能大于1024*768。超过这个尺寸就无法显示。这一点我觉得应该在文档里注明的,但是并没有。也许写在别的地方了,但我没有发现。有很多时候文档并不会写的事无巨细,在网上也找不到与之相关的帖子。
- 总之,又是对素材和场景一番修改,总算是可以运行了。但是如之前所说,CIFilter 是处理静态图片的,而这个 Distortion 在设定好,center,scale 等等参数之后,效果是固定的。比如这个圆心就在那个位置,然后半径就是那么大,而我需要的是动态的,是半径逐渐变大的波动效果。
- 电影的原理不就是每秒24帧,本质上也都是静态图片。想到这,心里也就有了答案。只要在一秒以内更新24次以上就行了,而游戏引擎自身携带的 update 方法就是每秒更新60次,所以把变化的方法写在 update 方法里就能实现动态效果了:
最终效果
虽然说不应该边想设定边写程序,但我说的是应该将设计与实现分开,其实上面写的这个过程是想法的验证,应该算是设计的一部分。做游戏绝对需要奇思妙想,但将想法落地,要比想象中困难的多,而且很有可能完成的东西,的确实现了想要的效果,但却和想象中的不一样。
在整个游戏的构思慢慢成型之前,这种横冲直撞的试错阶段会持续很长时间,新接触的时候尤其如此。这是一个验证的过程,也是一个妥协的过程。也正因为这样,这种耗时费力的工作应尽量在设定阶段完成。如果像我一样,想到什么做什么,很有可能会因为,不断在发散思维和逻辑思维之间做转换,且因为想法验证出错而打击积极性,搞得自己精疲力尽。
没有文档或明确的目标,就是需求不明确。需求不明确,就没法做需求分析。没有需求分析,就没法有条理的做设计。没有设计,也就没法做功能实现和编程。
从外到里的写作:边写对白边寻找场景,边写场景边寻找故事———是最没有创造力的方法。 ——罗伯特麦基《故事》
总结了失败经验,才发现动手去做所花费时间反倒不是最长的,而做设定也是需要耗费大量心血的。
通过这个经历也折射出第二个我没意识到的问题:
问题之二:做独立游戏花费的时间往往超乎想象
很多成名老哥都说过这个问题,像高瞰老师和吹哥都说过:人们往往对项目周期估计不足。但我听到这些忠告的时候都是项目进行到中后段,进退两难的时候了,并没有起到什么作用。所以我希望你看到这个建议的时候,还来得及。
设定需要异想天开,然后还要验证这些想法能否实现。寻找灵感和处理bug都需要时间,如果你做的是个全新的东西,出了问题也只有你自己能帮你。因为别人没做过,也就没遇到过这些问题,自然也无法在网上找到解答,时间上更是没法保证。
我应该建议:对项目周期有足够的估计,但这也可能是一句废话。
尝试新的东西,总会有新的问题。而新的问题谁也不知道什么时候能解决。所以,要做好足够的心理准备,慎重选择开始的时间和地点。在什么时间,什么样的地点,看似微不足道,但如果对开发周期估计不足,这些因素反倒会成为最棘手的阻碍。
时间
兼职去搞听起来不错,下班之后总能抽出点时间吧。但是如果是游戏开发相关的职业,工作压力还是挺大的。加班是常态,回家之后倒头就睡,连周六日都在家中补觉。就算时间抽得出来,精力也抽不出来。如果不是 it 相关,就算有时间,也得花大把时间从头学起。学习是最累的,而世上大多数工作都不轻松,等费劲心思鼓动起来的寥寥热情与精力消耗殆尽,却连基本的动画与移动,都无法做到同步的时候,也定会产生放弃的念头。但只要意志坚定坚持下去,无论是以上哪一种情况都会有成效的,只是无法改变兼职所带来的事倍功半。
只有全身心投入,才能以最大的效率去随心所欲的创作。但无论做什么,将自己全部的时间投入进去势必会打乱生活重心。而在这样的情况下,对开发周期估计不足,就可能会消耗大量的成本。时间成本自不必说,生活成本超支的痛苦往往超乎每一个社会新鲜人的想象。宫崎骏曾经说过:要想随心所欲的创作就要攒够五年的生活费。可能原话不是这么说的,但说的是这个意思。
时间总会不知不觉的流失,但究竟时间都花在哪了?以我自己的情况举例,首先是毕业后的这个时间点可以说非常糟糕,不确定性太多,导致项目在前期时一再中断,拖长了周期。但无论怎样,凭着下班后抽出来的空闲时间兼职做了一段时间之后,感觉自己也积攒了一些经验,项目也初见雏形。但如果集中力量全职去做的,觉得三个月就能做出成品,遂辞职回家。
嘿,愣头青,什么也不懂,怎么可能会估计的准呢。
当初说好三个月,三个月之后又三个月,三个月之后又三个月
就像上面提过的,验证新的想法并将其实现,耗时费力。但有很多看似普通的问题,不一定很费脑子,但做起来非常麻烦。比如最基本的角色移动,想起来很简单:玩家发出移动命令,人物移动到指定地点同时播放走路的动画,到达地点人物停止移动并停止动画。
但是真正编程起来就很复杂:
什么时候开始移动?是点击手机屏幕之后,还是点击的手指抬起之后。
是匀速移动,还是先加速再匀速?
就先设定成匀速移动,但是如果在角色第一步抬脚的动画开始的时候就移动,那人物抬起的脚还在空中,人物已经漂移了,不行,太突兀了。
必须要在人物第一步落地之后再开始移动,这就需要把人物走路动画分成,抬脚,走路循环,停止走路三种动画。
OK,设定完动画状态,使人物在抬脚动画播放完之后,再触发移动方法,但是人物已经移动到指定地点了,人物的动画还没播放完,还在迈步,怎么处理这个情况呢?
开始的时候,我每天处理最多的都是这些细枝末节的问题,因为是新手,没接触过自然也考虑不到那些细节。对我来说这个过程没法避免,只有通过不断的犯错和学习,才能最终找到合适的解决方案:
人物走路逻辑图
单就这一个问题,在脑海中设想,也就三分钟,但做起来两天都不一定能从各种 bug 里找到出路。这还没涉及到场景之间的转换问题;战斗系统里人物的 ai 问题;另外我用的是横版过关的视角,还要处理人物离屏幕远近导致的上下关系变化;还得考虑人物离屏幕远近的大小关系,从而实现透视效果,等等等等。
时间就是在这样不断解决零散问题中悄悄流逝的。
地点
当时间超出预期的时候,你会开始变得焦躁不安,而且日渐严重。而长时间深入简出使你在亲戚中声明远扬,你的卧室会变成十里八村七大姑八大姨钟爱的旅游景点,各路没听说过的陌生亲戚会强装客套满脸堆笑以示关心的挤破门来想要一睹你超凡脱俗的尊容。让本就心急如焚注意力难以集中的你更加精神涣散。所以这里有个衷心建议:除非是你自己的房子,你一个人住,否则千万不要在家里工作。
很多时候你自己最清楚风险是怎样的,而你身边的人往往觉得你不知道,会不断提醒你。也许你不往心里去,因为你自己最清楚自己在追求什么,但谁也耐不住这样日复一日的干扰。给自己一个良好的工作环境能提升不少效率,这个地点设在哪里都行,就是千万别设在家里。
时机
说了这么多,那到底什么情况下开始比较好?在我看来,做独立游戏的最佳时机应该是在大学阶段。
我特别后悔,为何没有在大一时萌生想法的时候就开始。即使起初没找到入门的途径,也应该坚持求索。大学时期,只要不是励志搞学术,只单单应付考试的话,相信绝大多数人都有充裕的业余时间。如果你是游戏开发相关专业,编程,美术,数字多媒体艺术等等的在校大学生,并且有做游戏想法,那我建议你马上,立刻动手。也不用花太多时间,只要每天拿出两小时捣鼓捣鼓,一年下来也应该能做个差不多的东西出来。四年下来能积攒不少经验,即使只做出了一个游戏,那也会是个不错的毕业设计,运气好还能靠它挣点零花钱。
当然,刚开始立项要紧凑,不要铺张。先做设定,慢慢验证,想法成型之后再做成品。
第一,大学时期精力充沛。第二,大学时期食宿不用操心。第三,也是最主要的,大学时期有时间,时间是最大的本钱。并且这也算是课余练习,失败了也无所谓。
简单建议
1.选择游戏引擎
对于初学者而言,无论是什么平台,相对 3d 引擎而言,选择先从 2d 游戏引擎开始,会更轻松一些,至少可以先了解一下游戏的开发机制。而我自己选择了 2d 引擎之后,平台上则选择了手机平台,因为它相对来说更加轻量化。
我最开始也打算做 3d 的,但是建模这一块完全不行。大学时为了学分也选修过 maya,材质啊,光照啊,折射率啊已经很头疼了。除此之外,建模相当于用鼠标做雕塑,和所有技能一样需要时间练习,没个一年半载熟练不了。我开始的时候以为只需要三个月就能把游戏完成,哪有心思去学习建模啊。
不过,要是决心做 3d,建模是必须要掌握的,不然也要有一个会建模的伙伴。虽然我自己是单干,但我是找不到人同时又没钱雇人。有条件的话还是要找合作伙伴,毕竟多人分工总要快过一人苦撑。
选择 2d 引擎,还有一个原因是我囊中羞涩,掏不出高昂的授权费。我最开始的第一选择其实是 unity,但1000刀授权费把我劝退了(现在据说不需要了),2d 引擎中很多都是开源的。
立项的时时候,游戏引擎的第一选择其实是 cocos2dx,但上学的时候 cpp 并没有学好,而且我一直在说,三个月吗,心急火燎的,根本没心思去看那个乱成一团的类库。当时我对 iOS 开发非常感兴趣,一直想学习一下 Object-C。再加上苹果公司看好手机游戏的前景,发布了自己的游戏引擎。我本着学习 Object-C 的初心,而且当时发布的苹果游戏引擎 SpriteKit 并不比其他 2d 引擎差多少,再加上 iOS 又不是开源,苹果自家引擎兼容性上不会有太多问题,遂决定使用 Sprite kit。但这算是踩了一个坑。
在这里再说一个我自己的建议:无论是 3d 引擎还是 2d 引擎,应该选择那个被业内广泛使用的游戏引擎。更流行代表运行更稳定,功能更强大,即使出现了各种各样的问题,因为使用的人多也就有更活跃的社区,更大几率能找到相似的解决方案,即使是遇上了引擎自己的 bug,也会因为庞大的市场压力,厂家会在更短的时间里发布补丁修复。即使项目不成功烂尾了,也能凭着积攒下的经验获得更多新的工作机会,毕竟使用相同引擎的人多。
我学习游戏引擎的主要方式是看官方文档,主要难点是英文。关键是掌握游戏引擎使用的计算机语言,比如 cocos2dx 是 cpp,unity 是c#,我用的 spritekit 是 oc。之后就是熟悉引擎的各种方法,然后就可以开工了。
2.美术
我在美术上能说的乏善可陈,因为我自己不会画画,吃了不少亏。唯一能有点价值的就是,一定要控制素材的大小。虽说素材越大细节越好,但是导入到游戏中之后占用的内存可不等于素材在磁盘上占用的空间,有的时候占用的内存是磁盘上的四倍大小。而如果用帧动画的话也要控制帧数,而且每一帧的素材也要尽量小一点,毕竟帧数越多,占用的内存就越大。素材应该在尽量保有细节的情况下尽量小,用压缩工具给图片素材瘦身是必须的。
3.一些建议
在实际开发当中,update 方法是游戏引擎的核心。我一般是拿来判断状态和实现逻辑。
光照效果非常昂贵,慎重使用。要想在手机上使用华丽的光照系统,要对场景大小严格控制。
多线程不是必须的,但如果打算用无 loading 机制,应该花心思好好设计一个多线程系统。
谨慎将所有资源都载入到一个关卡里,无论最开始的时候它占用的内存有多小。除非游戏已经定型,否则永远不知道还要往里加多少东西,一旦关卡的系统骨架确定,再去修改资源载入逻辑等于伤筋动骨。
内存管理是重中之重,千万别装太多素材让内存爆了。iOS 上的内存泄漏是主要课题,这一点如果有设定文档指引按部就班的写代码,仔细一点就可以避免。可别像我一样,想到哪写到哪,等开发时间长了,自己写过的代码自己都能忘,什么地方强引用,什么地方内存没释放肯定也记不清了,出问题了根本找不着北。
虽然开发过程艰辛且漫长,煎熬且令人疯狂。但是日复一日的努力,最终会在某一天化腐朽为神奇。当第一次在脑中灵光一闪的情景,不佳思索的化作代码,全新而又不存在的东西一如自己的设想,在程序里没有报错一次通过,并分毫不差的呈现在眼前的时候,就是最爽的精神刺激。
现实的差距
经过无数思维停滞的下午,熬过无数辗转难眠的午夜,数不清多少次徘徊于放弃的边缘,凭着仅存的一丝梦想的余烬,隐忍着将所有模块一一完成,终于第一次运行设想中的游戏流程。
初版截图
心情从期待到兴奋,又从兴奋到失望。因自我感觉良好而产生的零星闪光点也在多次运行后无影无踪。
初版人物
平庸,溢于言表的平庸,甚至有点不堪入目。实现功能和做出表达是两回事,就好比实现了人物击打敌人的功能并不代表一定能获得打击感。游戏除了程序以外的,应该还需要别的什么,不可名状的东西。这一点我作为玩家时就知道,但真的动手做起来,是如此的手足无措。如果你做的是个全新的设计,那这个世界上没人能告诉你,怎样才能把它实现,因为别人没做过。当尝试了各种自己能想到的方法,依然达不到心中的效果,我才真正认识到什么叫不可名状。
从小到大也玩了不少游戏,多年游玩的经历让我对高标准习以为常,我自己并没意识到玩家其实是很挑剔的。那些脱颖而出的作品,我不假思索的认为那就是游戏本该有的样子。但如果想做出那样的优秀作品,就必须同那些作品一样,与那些默默耕耘多年的大厂竞争。而我自己含辛茹苦做出来的初版样品,连我自己都没法说服。
绝望。
要放弃吗?转眼间已经做了一年半了,各大公司的校招早就已经开始招聘我下一届的学生了。社会招聘,我有什么呢,一个平庸的半成品。这么长时间的心血付之东流,心里也过不去。
做下去?困难高耸入云,根本看不到尽头。骑虎难下,进退两难。
未完待续
暂无关于此日志的评论。