游戏开发论坛

 找回密码
 立即注册
搜索
查看: 9030|回复: 1

格斗游戏的招式指令判断

[复制链接]

98

主题

784

帖子

4493

积分

版主

Rank: 7Rank: 7Rank: 7

积分
4493
发表于 2015-11-2 10:11:27 | 显示全部楼层 |阅读模式
本帖最后由 小篱 于 2015-11-2 17:20 编辑

  以KOF为例 : 236a 是红丸的雷拳,624a 是撑地转。那么 在键盘指令输入到游戏内,是如何去进行指令匹配的?需不需要考虑输入时间,进行清空输入缓冲区等等。

  1,有效输入与无效输入


  首先,你必须明白游戏中有有效输入和无效输入2个概念,大多时候输入是有效的,但是当你的角色处于一些动作帧的时候,帧的属性(按现在的理解就是“填表内容”)会告诉程序2个信息:一是这帧时用户输入是否有效,二是这帧时用户输入缓存(按照现在的概念来看,应该叫做“输入缓存”)是否清空。这里有一个关键在于:在逻辑的世界中(并非你肉眼看到的,首先你要能做动作游戏,你的资质必须支持你看的见共存的两个世界——现实世界和逻辑世界,他们是耦合的,但并不是完全互相映射的)无效输入和清理缓存的帧,当你看到图形的时候未必能够直接联想的到关系,这需要很有经验的策划和美术的配合(这是现代分工法,当年做动作游戏的这一批人,要么就是美术型策划,要么都是能写逻辑代码的)才能制作好。

  2,“输入缓存”的产生和遍历

  在且仅在用户输入有效的时候,我们会向缓存中写入我们的操作记录,这个结构是非常简单的,如果用伪代码写出来,他就是:

  1. KeyRecord = {"key":按钮,"time":按下时间}
复制代码

  其中按钮是这条记录代表他按了什么按钮,对于这个是有一个特殊处理的:

  1)方向按钮,抬起的时候产生KeyRecord,记录时间却是按下时间,再按住方向按钮没有抬起的时候,也会周期性的增加KeyRecord,time都是根据周期开始时候获得的。

  2)动作按钮(对应游戏机上ABCXYZ等),抬起的时候产生KeyRecord,记录时间也是抬起时间。

  最后我们会在内存中有一串玩家输入的2维数组(为什么是二维?因为游戏机有2-4个手柄,我们需要第一维记录是哪个手柄发起的),去记录这个KeyRecord。当然没一个角色的每一个招式的出招表,也是用这个结构的一个数组array of KeyRecord。

  在每次记录的时候,我们还需要做两件事情:

  1,)根据游戏设定的“操作指令输入时间”,通常是100帧(如果一个人用“秒”来说这类游戏的单位,就证明了他压根没有开发过这类游戏,都是在想当然的,因为在那个环境里,你能得到的时间只有帧,所以你会发现现在一些模拟环境下,你启用模拟器加速,你的操作可能会要求更高才能发出招),我们要吧数组中“超时”的KeyRecord全部删除,通常这里很容易优化,就是循环到第一个不需要删除的就好了(这是小聪明,现在我仍然觉得有点危险)。

  2)遍历角色每一个招式,首先判断最后一个按键是否符合现在创建的这个KeyRecord(也就是最新输入,这也是小聪明优化,但是依然说不出有什么不好的),首先如果还有1条以上符合这个条件,那么在针对这些符合条件的去查询他们的出招过程是否符合了出招。

  3,当符合了出招表的输入产生了,我们要干什么?

  只是符合了出招条件,并不等于我们必须放出招式,这里是一个很重要的Key,我们还有很多逻辑判断要做:

  1)怎样找出我最想放的是哪招?

  当你在遍历“输入缓存”的时候,你很有可能找到两条甚至更多条都符合你想出招的操作,这是很常见的,比如(我这里就不用KeyRecord了,因为写时间,地球人是写不出来的,我就写一下这个“缓存”里面有过哪些按钮):↓↘→↙↓→↘→此时我按下的是A,这里还必须先让你知道一件事情,就是这里的方向,是面对你角色Flip过得,比如你的角色面向左边的时候按左,记录在缓存里面的是按右。你会发现这样的记录并不奇怪,如果按照出招表(玩家通常都是在游戏攻略得知的出招表),他可能什么都发不出来,而是砍了轻刀(在那一作侍魂A是轻刀B是中刀C是重刀D是踢腿Select是挑衅),但事实上用户这时候的意思很可能有3个(如果用户操作的是霸王丸):

  可能性1:他就是想来个轻刀。

  可能性2:旋风斩:我自己给的称呼,反正就是飞一个龙卷风出去,“游戏配置表”中是↓→A,游戏攻略中给出的↓↘→A or B or C,因为写攻略的人并不知道这其实有3个技能。

  可能性3:升龙斩:也是我自己起的名,就是刀转两下再来个遨游跟的那个,→↓↘A,当然槽点还是跟旋风斩一样。

  然而,得出这些以后,我们还会经过几个步骤,来得出最后我最想放的是哪招,为什么要有这样一个过程?因为玩家可能觉得自己的操作是非常符合出招表的,但是出招表给出的并不是官方的数据配置表,而且配合输入设备的一些限制,总是会有一些“噪音”被加入到你的操作过程中,如果我们严格的按照没有“噪音”的来做,你会发现一个游戏根本搓不出招,手感极烂(这个你可以在真说侍魂武士道列传,这个侍魂的RPG版本中体验到有多让你抓狂):

  Step1:目前是否接受按键,不接受啥都不做(接收条件上面说了)。

  Step2:列出一个列表,把这些招式放入表里,并且定个“亲密度”,并且根据亲密度把表从上到下排列。亲密度是根据最接近尾部的那次操作来算的,我们还是看范例中的“缓存”,然后编个号:1↓,2↘,3→,4↙,5↓,6→,7↘,8→,9A(这是最新加入的,也是本次按键)。那么旋风斩“最近一次”符合输入是569,升龙斩最近一次符合是3579,取(缓存长度-最大2个按钮次数之差/需要按键次数-abs(最后2次按键次数差-平均按键次数差))得到亲密度(很可能小于0,不过这只是比大小的,所以并没什么问题),则可以看出:

  旋风斩:需要按键次数=3,最大2个按钮次数之差(这个名词真不好定,都很拗口)=3(来自9-6)-1(来自6-5)=2,最后2次按键次数差=9-6=3,平均按键次数差=(3+1)/2=2,结果就是9-1-abs(2-3)=7(长度是9)

  升龙斩:需要按键次数=4,最大2个按钮次数之差=0(都是2),最后2次按键次数差=2,平均按键次数差=2,那么结果就是9-0-0=9。

  因此我们这时候得到了亲密度列表顺序是:升龙斩→旋风斩。然后我们再把单个按键企图做的动作(当前按键是A,所以是轻刀)push到这个列表的最后。

  2)得出了这个列表干什么呢?

  并不是得出列表我立即就放了第一个动作了,那是不可能的事情。我们按照列表的顺序遍历,判断当前的情况是否可以转入这个动作,如果可以,那么就进入这个动作并且return,否则就继续遍历下一个,直到列表没货。判断这个动作是否有效的依据是:

  a)当前是否有武器,这是侍魂的一个特殊处理点,不适用于所有游戏,但这也是一层优化,其实原本完全可以根据当前角色的动作来确定是否能够Cancel的,但是这样就算设计师配置表都会很复杂,所以干脆增加了“持有武器”这个boolean,要知道在侍魂里面,旋风斩和升龙斩都是必须有武器才能放的,所以当你“持有武器”==false的时候,就可以直接下一个loop了。

  b)当前的动作是否可以被现在判断的这个动作Cancel,之前有一篇我也发在GameRes的帖子[经验心得]动作游戏中连招的实现说到了关于Cancel的概念。如果不能Cancel,那么当前判断的这个动作不能释放。

  3)找到或者找不到合适的动作,我都要干什么?

  通过上面一步,我们也许能找到一个合适的动作,作为现在要做的动作,那么就让角色立即做那个动作,并且清空这个“缓存”。如果没有找到,则不执行任何改变。

17

主题

1629

帖子

5982

积分

论坛元老

Rank: 8Rank: 8

积分
5982
QQ
发表于 2015-11-2 11:12:10 | 显示全部楼层
这么牛逼不如写个DEMO
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2024-12-22 11:51

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表