【CSDN 萨德基】往后一周,不少人被《羊了个羊》此款格斗游戏虐的一干二净,有多少个再玩一把的想法,就有无数次被打进梦魇的悲凉,甚至还有人评价道:什么事都可以往后,除了《羊了个羊》第二关。因此,有使用者埋怨是合作开发人员蓄意蕨科角制作死迷宫。不过在责任编辑译者老张一探究竟以后,才发现并非合作开发人员蕨科角,而是该格斗游戏的这类,就有很多天然的坑。
译者 | 合作开发格斗游戏的老张
白眉林 | 颤抖地月
公司出品 | CSDN(ID:CSDNnews)
昨天有好友和我说:最近有位叫《羊了个羊》的格斗游戏伤风败俗,是昂西桑县玩了,你能重制一个不?话说那次玩休闲格斗游戏却是在几年前,但是好友之托必须挺身啊,跑过来,开整!不过,贪婪是撒旦,直到此刻,老张也未能亲自动手玩五局美版格斗游戏,不知道是格斗游戏出口处设计得太隐密却是互联网读取很慢,无论手机端却是PC端,格斗游戏都逗留在如下表所示介面。
所以本次格斗游戏的重制,完全是基于各音频网站云参访的结果,好在格斗游戏的动作游戏不是特别难理解。重制采用的合作应用软件是Godot Engine(采用其它工具合作开发基本原理也是相近的),目前项目已经开放源码到了GitCode:Godot版《羊了个羊》https://gitcode.net/hello_tute/SheepASheep。
接下去我将通过米芾格斗游戏的方式推断一下那个小格斗游戏的实现基本原理,责任编辑主要就面向全国对格斗游戏合作开发有兴趣的好友,热烈欢迎大家多提意见建议。
没错看到《羊了个羊》,老张首先想到当年的《特集》,不过有网友曝料,该格斗游戏先进经验了《3tiles》。瞄了眼《3tiles》,是比较相近。扎格列,那个格斗游戏的动作游戏并没有什么过于出色的地方,算是个平庸的低千卡休闲格斗游戏。
之所以成为热门话题作品,主要就是因为它的第2关极为低的报检率,一下子招来了为数众多玩者的挑战贪婪。而如今那个低报检率也被互联网上的为数众多玩者详解,第2关其实大概率上这类是个死局。是合作开发人员蓄意蕨科角设了死局么?先卖个卖关子,我们先谈谈格斗游戏的合作开发,然后您自己就会有答案了。
格斗游戏的整体很简单,但其中有几个实现的重点需要注意:
牌堆的结构及其数据结构
最初,我还真被这复杂的牌堆结构蒙住了,但仔细研究一番发现,无论多么复杂的牌堆,其实都是由如下表所示三种牌堆模式组合拼凑而成的。
虽然上图中体现不是很明显,但不难猜想出,第三种牌堆模式B 的存在,那是:
对于牌堆模式A,有些好友会迫不及待地用队列或栈实现它,这样做有两个缺点:
实际上无论牌堆模式A、B却是C,都不过是3维数组结构,上图中模式A看起来特殊,无非是它的x,y维度都为1罢了。而三种牌堆的区别也无非是当一张窗口牌被取走,检查牌堆是否出现新的窗口牌的方法罢了。
牌堆模式A
牌堆模式B
牌堆模式C
牌堆的数据结构
我将其定义为MContainerBase基类
最基础的牌堆是一个 xyz的三维数组,我们可以采用一切方法构造想要的排队形状:柱形、条形、甚至金字塔形。这都不会影响后面程序的实现。
项目中为了增加那个大方块的多样性,我还给它设置了如下表所示的遮罩,这是格斗游戏中CSDN文字的由来。当然我们还可以通过遮罩来自由定义窗口牌,这部分就请大家自由发挥了。
如何检测和更新可拾取的牌
三种牌堆模式分别派生自MContainerBase,并对应着如下表所示三种检测方式:
牌堆模式A
仅检测自己正上方是否有牌
牌堆模式B
检测自己上方两方位是否有牌
牌堆模式C
检测自己上方四方位是否有牌
在Godot中,这三种牌堆模式还可以通过场景节点制作成预制体,这样迷宫设计师就可以轻松地制作出美观的迷宫了。
简单了解格斗游戏规则后,我们就不难推导出,每个迷宫能被通过的一个必要条件是每一种图案的总数,必须能被3整除。实现方法如下表所示:
其中字典initial_tiles 的key对应着每一种图案,后面的value对应着这一关该图案出现的对数(此处1对等于3个)。按照value乘以3的数量存入数组tiles(下文称之为:待发牌池),然后把待发牌池中的元素打乱顺序,等待发牌。
关于格斗游戏中的坑
很多好友埋怨:合作开发人员蓄意蕨科角制作死迷宫。其实不然,他无须蓄意蕨科角,因为那个格斗游戏这类就有很多天然的坑,如果不使劲填坑,它们自不过然就属于你了。而这里就隐藏了几个可致命的坑:乍一看,待发牌池中所有的图案都可以被3整除那么一定可以报检?那可不一定:
只有桌面牌堆中牌的数量和待发牌池牌数一致,所有的牌才能落地,而格斗游戏中桌面牌堆到底有多少(层)这类是个迷。并且如果没猜错的话,在每五局设计者先要确保牌堆形状好看,然后再使堆牌数和待发池的牌数一致。二者哪怕差1个,也会造成死局。
上文说了,桌面牌数和待发牌池的牌数一致只是过关的必要而非充分条件。即使该条件满足,如果相对于牌桌上的牌数以及图案数量,窗口牌数太少,也会造成死局。比如下表所示面那个极端的例子:假设格斗游戏共有 15种花色,而牌桌上只有那个模式A牌堆,它有90张牌。那么玩者只要在连续7次拾牌时没有遇到3个相同图案的牌,就必死无疑了。
其实那个格斗游戏,一方面要控制迷宫的难度,另一方面又要保证能报检这类是一个相当困难的问题(至少老张没有想出办法)。而设计者反其道而行之,(可能)没有花力气去设计算法,把坑留给玩者,得到了极低的报检率,反而制造了热门话题并形成爆款。如此说来,这确实是个抖机灵的设计。但老张认为这种设计在格斗游戏策划中是不宜被先进经验的,就像现在市面上泛滥的悬疑剧,开始埋坑无数,吊足观众胃口,最后烂尾不了了之一样,长此以往观众(玩者)对于悬疑剧(格斗游戏)的信任感就被消费殆尽了。
洗牌道具的实现
洗牌的实现基本原理很简单,把当前桌面的牌记录在一个数组tiles中,当需要洗牌时,先打乱一下数组中牌的顺序,然后让桌面上每一张牌到tiles中重新取一个值。再来个眼花缭乱点的动画,还真挺像那么回事儿。
遮罩文件的读取
这里要夸一下Godot Engine,它的很多功能真是方便,比如下表所示面那个str2var它可以简单粗暴地直接把字符串转换成对象类型。
对象间的通信
那个小格斗游戏中存在大量的对象间的通信需求:牌和牌之间、牌和牌堆之间、牌和迷宫之间、牌堆和迷宫之间。为了快速实现格斗游戏,我大量采用了Godot Engine的Group机制,不得不说Group是Godot Engine最赞的设计之一。
小格斗游戏《羊了个羊》,从策划和合作开发的角度来看并不困难,不过瑕疵竟然能够成为噱头,也让人不得不感慨格斗游戏世界真的一切皆有可能啊。
译者简介:
合作开发格斗游戏的老张,高校教师、技术专栏译者、独立格斗游戏合作开发者,CSDN博客地址:https://blog.csdn.net/ttm2d
发表评论