前言
必杀技系统是格斗游戏中必不可少的元素,要触发角色的必杀技,必须在一个很短的时间内,准确无误地输入一个按键序列,比如下表中街霸角色隆的部分必杀技:
必杀技 | 按键序列 |
---|---|
波动拳 | 下,前,拳 |
升龙拳 | 前,下,前,拳 |
在上表中还能发现一个隐藏问题,例如:波动拳的
下,前,拳
是升龙拳前,下,前,拳
的子序列,如果处理不当那么升龙拳可能永远不会被触发。
基本原理
直接使用帧作为计时单位,既准确又方便
当输入(事件)队列和出招表的每一个必杀比较时,如果队列的长度大于必杀的指令长度,需要删除队列头部的元素以使它们长度相同
这个系统只处理用户输入,完整实现角色的必杀技还需要结合状态机,比如用户输入了下,前,拳
,本系统把用户想触发波动拳的消息交发送给状态机,状态机决定角色是否能发出波动拳。
上面隐藏问题的处理,实际上就是把处理升龙拳的优先级提前,实际上就是在字典中把升龙拳放前面:
var combos : Dictionary = {
"Shoryuken" : [RIGHT,DOWN,RIGHT,A] ,
"Hadoken" : [DOWN,RIGHT,A]
}
完整的GDScript版必杀技输入系统
加了注释
# 格斗必杀技输入系统 V3
extends Node
enum {
NONE ,UP,DOWN,LEFT,RIGHT,A,B} #和必杀技相关的事件
var action_queue : Array = []#输入的事件队列,NONE事件会被过滤掉
var counter := 0#计时(数)器
var is_reading := false#标记是否在输入必杀技
const MAX_COUNT := 100#最大帧数
### 记录大招的字典
var combos : Dictionary = {
"Shoryuken" : [RIGHT,DOWN,RIGHT,A] ,
"Hadoken" : [DOWN,RIGHT,A]
}
func _process(delta):
var current_action = read_action()
if current_action != NONE:
if not is_reading:
is_reading = true
action_queue.push_back(current_action)
for combo_name in combos:
if check_combo(action_queue,combos[combo_name]):
trigger_combo(combo_name)
print( combo_name )
reset()
break
if is_reading:
counter += 1
if counter >= MAX_COUNT:#如果超出了输入时限。则系统归零
reset()
#读入输入事件
func read_action():
var action = NONE
if Input.is_action_just_pressed("ui_up"):
action = UP
if Input.is_action_just_pressed("ui_down"):
action = DOWN
if Input.is_action_just_pressed("ui_left"):
action = LEFT
if Input.is_action_just_pressed("ui_right"):
action = RIGHT
if Input.is_action_just_pressed("ui_j"):
action = A
if Input.is_action_just_pressed("ui_k"):
action = B
return action
#检查是否有大招成功被激发
func check_combo(s,t):
if s.size() < t.size():
return false
var c
if s.size() > t.size():
c = s.duplicate()
c.invert()
c.resize(t.size())
c.invert()
else:
c = s
for i in range(t.size()):
if c[i] != t[i]:
return false
return true
#触发角色的大招
func trigger_combo(combo_name):
get_tree().call_group("Ryu","Combo",combo_name)
#系统归零
func reset():
action_queue.clear()#清空输入队列
counter = 0#计时器清零
is_reading = false
来源:oschina
链接:https://my.oschina.net/u/4306257/blog/4688686