文/命运Sniper
前段时间和几个小伙伴一起参加了一个GameJam(在几天时间内根据指定的主体快速制作一款小游戏的活动)Ludum Dare 41,由于是第一次参加GameJam,感触颇深,其中有很多和游戏设计、游戏开发方面相关的体验,觉得可以记下来。
由于是回忆性质的记录,行文逻辑可能会欠佳,见谅。
最后的成品链接:https://ldjam.com/events/ludum-dare/41/fast-food,欢迎围观。
主题
Ludum Dare 41的主题是“Combine 2 Incompatible Genres”——“组合2个不兼容的流派”。
说实话看到这个主题时我们最开始是比较懵逼的,就像当时讨论区里有人提到的“如果2个流派真的不兼容,那么它们是没有办法被组合的”。
不过扩展开想,“不兼容”这个词的意思是很宽泛的,应该将思路放在将2个差异性很大的玩法、风格结合在一起上,只要体现出“正常情况下这2者不会同时出现”即可。
然后就开始头脑风暴,首先把能做的游戏类型都罗列出来。考虑到我们几个人经验都不多,想从简单的入手而且没人会捯饬shader,于是确定做2D。
2D中毙掉了一些肯定做不了的,比如剧本量比较大的游戏类型比如文字冒险,因为没人会写剧本,尤其是还得用英文写;比如音游,没人做过类似工作不知道坑有多深。
最后从能做的东西里开始想怎么组合,最好还能避开一些很容易想到不容易出彩,比如回合制的即时战斗游戏/即时战斗的回合制游戏,都是很常见的游戏类型,没想出什么在“组合”上体现出新意的点子,想到的点子都是在即时战斗或回合战斗本身上进行创新。
最后拿出了5个备选方案
1是结合2个不兼容的主题:老人和运动,做一个老年人运动会的游戏,包括老人坐在轮椅上赛跑、拿着拐杖竞走等等
2是用泡泡龙的思路玩俄罗斯方块,即将泡泡龙游戏中画面下方发射的泡泡替换为俄罗斯方块里的方块,通过墙壁的反弹在画面上方组合形成满行从而消除
3是三消/连连看 平台跳跃,在初始满屏幕不同颜色的方块上使用三消或连连看的形式消除一些方块,使得左下的小人能够通过跳跃、攀爬等方式到达右上的位置
4是打砖块 飞行射击,飞机发射的子弹是会反弹的,飞船需要接住反弹回的子弹再次弹出去以保证能在最短时间内清版
5是竞速 模拟餐厅,用赛车游戏的思路收集跑道上的食材并完成菜品制作的过程
实际上每个方案都有其优劣势,对优劣势进行了一番讨论 投票后,最后选择了竞速 模拟餐厅的方案。
设计功能
大体的方向定了就要设计具体游戏中的游戏目标、玩法功能和预期难点。
最初提出这个方案的同学的想法是通过在赛道上设计一些做菜的材料、工具和障碍,让赛车——也就是盘子——按照顺序拿取材料、加工材料、避开障碍,最后通过终点。
预期是将做菜的部分设计得带有一定的解谜要素和2D动作类游戏的操作要素,比如如何在传送带上接住定时落下的沙拉同时避开铁锤等等。
但后来我们讨论了一下觉得赛车本身是需要一定的快速的元素的,周围环境一直变动,而这种2D动作解谜的过程是一个慢速的过程,是长时间待在一个小范围内,这2者合一起会显得十分割裂,即先在一个场景下完成解谜,然后迅速开车冲到下一个场景,本质上还是2个单独的游戏。
另外解谜的关卡设计和开发难度不低,但是很容易就被玩通了,感觉很亏。而且解谜的部分介绍起来挺复杂的,要告诉玩家能做什么不能做什么,通常的解谜游戏是靠循序渐进的关卡逐渐丰富解谜中的元素,我们的小游戏没有这个时间。
于是决定要简化“做菜”里涉及到的步骤,在“动”的状态下进行做菜,于是想到用做三明治、汉堡的思路,在赛道上收集食材,然后组合到一起就成了菜品。
但是有了新的问题,赛车游戏的乐趣很大程度上在于PVP的部分,和其他玩家竞速,如果仅仅是在赛道上收集食材,那么最多也就是一个考验车技的事情,可能并不好玩。而且另一方面模拟餐厅的游戏的核心是食材和时间的规划,即不断有新的订单到来同时订单有时间限制,但是玩家做菜的速度是受限的,玩家需要规划好同一时间不同的厨具、员工干什么事情从而满足订单的内容和时间需求。
赛车游戏里时间需求很好体现,于是问题就是如何体现对食材的规划和与他人竞速的乐趣。本来如果是联机游戏可以让好几个玩家一起在赛道上跑,互相争抢食材,但是考虑到这个活动最后需要互评,如果强制多人游戏很多单人作者没法玩,不可取。
有同学想到一个点子,说我们一次放3道菜的材料到跑道上,玩家跑一圈做完一道菜之后,跑第二圈时出现一辆第一圈的“幽灵车”,玩家需要在避开自己第一圈的幽灵的情况下收集第二道菜的食材,这样间接产生竞速和争抢的效果。我们想了想觉得可行,然后就这么定了。
于是最后确定的游戏目标是分3次在赛道上根据要求的顺序拾取食材,同时注意减少碰撞和用时,预期难点除了赛车游戏本身的驾驶难度外,还有如何在前1-2圈规划好路线和食材拾取顺序,避免后面1-2圈被之前的自己过分挡路和碰撞,因此需要一定的背板和预判记忆的能力。
幽灵车功能
因为我们一共3个程序,因此我们把游戏分成3块:
关卡管理为核心的主菜单
赛车驾驶为核心的控制
幽灵车记录和重现
我是3个程序里unity经验最少的一个人,于是我提出自己做幽灵车记录和重现,因为万一做不出来还能直接把这个功能给砍了,不耽误总体进度,毕竟我们的第一要务是“做一个能玩的游戏”,做出来是第一位,功能够不够丰富是其次的。
最开始想到就是每一帧记录赛车的位置、速度、方向这些信息,然后下一圈复现,虽然记录量有点大,但是一圈时间最多也就1分钟,3600帧,感觉还行,就先写了试了一下,然后发现不行,幽灵车的运动一点都不平滑,一直在抖。
回想了一下之前依稀看过的一篇分析unity里update和fixedupdate函数的区别的文章,感觉这个跟2圈里实际帧之间的时间差有关。
于是改成了当玩家操作有变化时记录当前的车辆信息和操作信息,在第二圈里复现玩家的操作。这样运动上是平滑了,就是部分状态拐点(撞墙、撞障碍)的时候会有出现闪现的情况,也就是复现出的车辆位置和记录的位置有偏差。
现在想来,第一种方法卡顿的原因不一定是因为帧之间的时间差,即使是时间差其实也有方法可以解决,但是考虑到这种逐帧记录信息的方式太过于愚蠢和占用存储空间了,后来也没有再试过看能不能改进。
而第二种方法后来通过加入一些在定时、特定条件下强制记录车辆信息并复现的机制基本解决了闪现的问题。
写这部分功能的经历现在反思起来有2点问题
一是其实前面说的这一部分写、改的过程并不是连续的,最开始很粗糙地实现完整个录像功能后就和写赛车操控的同学合了一次代码,然后就开始帮着写赛车操控和关卡机制相关的东西了,后续改动都是在完成其他部分功能的测试中发现然后回头去改的。
但其中很多问题理论上是能在我这部分功能的独立测试里就能发现的,但我当时并没有怎么详细测试就去合代码了。
二是写这部分功能的时候模块化、解耦合做得不好,应该说是游戏控制这块的设计没有提前考虑清楚。因为对赛车的控制包括玩家驾驶时通过玩家的操作控制赛车RaceCar,和在幽灵车模式下通过记录中玩家的操作控制赛车AutoCar,但这2种控制的区别仅仅是输入来源不同,控制机理是一样的,因此相关功能函数是可以复用的。
实际上在最后的设计中,读取玩家的操作全部由AutoCar进行,由AutoCar向RaceCar提供当前赛车的具体控制行为,在玩家控制模式下AutoCar提供的就是玩家的当前输入,在幽灵车模式下AutoCar提供的就是记录中玩家现在的输入。
这样RaceCar只需要实现通过输入控制车怎么开就行了,不需要知道目前赛车处于真人模式还是幽灵车模式。
RaceCar里的控制信息都是从AutoCar的ControlNow结构体里读出来的,现在想来应该直接读出整个结构体的内容,不应该这么反复读。
分工合作
写完幽灵车功能的初稿之后我就开始去帮忙写赛车控制、物品拾取等等功能,但这一块的分工合作其实做得非常差。
现在想来,因为我们没有一个真正的总体策划和设计的角色(3个程序2个美术,而且没有谁作为拍板定方案的人),最开始仅仅确定了大致的玩法(赛车、拾取食材),但是一些细节设定比如一圈怎么算结束?食材是否刷新?障碍物有哪些等等并没有设计清楚就开始写了。于是这些设定都是后来边写边想的,也就是我和写赛车控制的同学2个人在想,很多地方考虑得很不充分。
例如他在写拾取食材的功能时觉得食材只要捡起来就行,对顺序没要求,但是这样要判断当前拾取的这个材料是否存在与目标列表里、显示在UI界面里“已拾取”部分的第几位需要一系列判断,特别麻烦。后来和我商量时我说我们应该对玩家的拾取顺序有要求,这样玩家只需要关注自己“下一个要的”是什么就够了,一下出现好几个物体时单一的目标会比较好判断。
现在反思的话,即使是这种小游戏,很多细节的设计也需要提前想好,形成文档,这既涉及到细节的合理性,比如我提出的只关注下一个的设计也有很大的问题;同时这对于分工合作写代码的场合下是十分重要的。
而且设计游戏远不止想一个点子这么简单,一份详细的设计书需要包括方方面面的细节设定,而这些设定都需要仔细推敲。例如我们这个游戏里最开始设计的是素材在全赛道随机刷新,因为我希望玩家是以保持速度为主要目标,根据“下一个材料”来选择捡材料还是绕过材料。但是后来根据玩家的反馈来看这种全图刷新对操作要求太高了,需要时刻保持紧张的精神和精细的操作,否则很容易就会错过或者捡错。于是后来改成了在特定位置并排刷3-4个材料对应每一道菜里当前位置需要的材料,玩家只需要捡起属于自己菜里的那一个就行。
看似简单实则不简单
最开始选择赛车游戏是因为我们觉得赛车游戏好做,但是实际上在做完最基本的赛车控制、拾取功能,整个游戏处于“最基本的能玩”状态下后,我发现赛车游戏水也很深。
首先镜头的跟随就是个大坑。
2D俯视角的镜头跟随要不要转动方向让车辆始终“向上开”?
如果镜头方向不跟随车的朝向转动,那么当车向下开时,对玩家来说车的左右就是颠倒的,很容易转错方向,尤其是我们这游戏里涉及到很多捡东西和避开障碍的元素,需要非常快速的反应,很容易出错。
但是如果跟随车的方向转动,那么镜头又会特别晃,因为赛车游戏中频繁的左右小幅度晃动调整方向的情况很常见,比如感觉自己有点偏左,于是先稍微右转一点然后立刻回正。但是这种晃动会让人有些发晕。
本来理想的方式是,让镜头朝向赛道的前方而不是朝向车面朝的方向,但是当时实在是没想到什么好的方式实现。
另一个大坑就是漂移。
最开始没打算加入漂移的功能的,但是游戏整体做完之后发现如果没有漂移,那么纯粹用方向键四平八稳地开车太无聊了,过弯只能减速,体验贼差,所以还是决定要做漂移。
但是漂移怎么实现?当时已经没时间去看网上别人提供的代码了,只能自己快速弄一个出来。
最开始的版本是当按shift时减速 快速转向,是个非常简陋的实现方式,仅仅能解决拐急弯时只能慢慢减速然后慢慢转向过弯的问题,但是和一般赛车游戏里的漂移差得太远了。
赛车游戏里的漂移至少得有“赛车前进方向和赛车朝向不同”这一点,虽然通过加入一个额外的赛车属性(在之前朝向的基础上加一个运动方向的属性)能够解决这个问题,但是按住shift后赛车朝向和运动方向分别怎么转动(肯定是一快一慢,但是快多少?慢多少?)?漂移状态下车怎么减速?运动方向向赛车朝向的恢复速度多快?按下shift进入漂移状态后shift继续按住和立刻松开有什么区别?
这里面设计到很多细节设计以及参数的问题,最后调试了挺长时间,感觉并没有获得太好的认同。
主要是作为写代码和调试的人,我已经很熟悉自己写出的漂移功能了,因此我玩起来6得1B,但是其他人,尤其是刚上手只是随便试玩一下没想要好好练习的玩家会觉得难得1B。但是即使我让周围的人试玩了一下他们表示难或者不像他们玩的游戏里的漂移手感之后,他们没法告诉我到底哪里不一样、应该怎么改。
因此在我体验不出问题在哪里、别人分析不出问题在哪里的情况下,我也不知道怎么改了。
美术和音乐
毫无疑问到目前为止我们这个游戏最大的亮点就是美术和音乐,几乎每个评论都赞了美术和音乐,真心感谢2位美术大佬的大腿。
我作为一个程序肯定是比较受伤的,尤其还是负责被“喷”的功能部分的程序。但是这也告诉我们,就像我们指责这是个看脸的世界一样,游戏也是有“脸”的,美术和音乐就是脸,好的美术和音乐对玩家第一印象的影响巨大。
而那些自以为牛逼哄哄的细节设定在没有好看的脸的情况下没人愿意去细细品,除了真·硬核玩家。
总结
我觉得自己在这次GameJam里算是收获颇丰,主要不是我谦虚,我只是想来打个酱油,结果莫名其妙就成了主程序,收获能不大么。
整个过程也让自己更加深刻地体会了一把做游戏的不容易,有很多问题如果不是自己亲自参与去做一个游戏是根本意识不到的,例如全局的设计、各模块的接口设计、游戏细节推敲等等。
因此推荐那些想做游戏、设计游戏的朋友,与其临渊羡鱼不如退而结网,只有把自己脑子里的脑洞落实到纸面上、代码里,才能正确评估自己的脑洞到底值几何。
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved