@@ -6,15 +6,26 @@ enum { LIGHT_ATTACK, HEAVY_ATTACK }
6
6
7
7
const SPEED_MOVE := 400.0
8
8
9
+ # This data structure stores the attack sequence of each combo as a key, and the
10
+ # corresponding animations and other data as values.
9
11
const COMBOS = {
10
- [LIGHT_ATTACK , LIGHT_ATTACK , LIGHT_ATTACK ]: ["light_combo_1" , "light_combo_2" , "light_combo_3" ],
11
- [HEAVY_ATTACK , HEAVY_ATTACK ]: ["heavy_combo_1" , "heavy_combo_2" ],
12
- [LIGHT_ATTACK , LIGHT_ATTACK , HEAVY_ATTACK ]: ["light_combo_1" , "light_combo_2" , "heavy_combo_2" ],
12
+ [LIGHT_ATTACK , LIGHT_ATTACK , LIGHT_ATTACK ]:
13
+ # Using a dictionary for each attack's data allows us to add any other data
14
+ # we need per-attack, like damage, status effects...
15
+ [{animation = "light_combo_1" }, {animation = "light_combo_2" }, {animation = "light_combo_3" }],
16
+ [HEAVY_ATTACK , HEAVY_ATTACK ]: [{animation = "heavy_combo_1" }, {animation = "heavy_combo_2" }],
17
+ [LIGHT_ATTACK , LIGHT_ATTACK , HEAVY_ATTACK ]:
18
+ [{animation = "light_combo_1" }, {animation = "light_combo_2" }, {animation = "heavy_combo_2" }],
13
19
}
14
20
21
+ # There's a limited timeframe to register the next attack for each playing
22
+ # attack animation. This variable gets set to true from the animation to allow
23
+ # the player to use the next attack.
15
24
var accept_next_attack := true setget set_accept_next_attack
16
25
17
26
var _state = States .MOVE
27
+ # We store the list of attacks the player used as part of the current combo
28
+ # here. See the _attack() function to see how we use this.
18
29
var _combo_current := []
19
30
20
31
onready var _skin := $ Skin
@@ -35,6 +46,7 @@ func _unhandled_input(event: InputEvent) -> void:
35
46
_attack (HEAVY_ATTACK )
36
47
37
48
49
+ # This handles forward and back movement when the player isn't attacking.
38
50
func _physics_process (delta : float ) -> void :
39
51
if _state != States .MOVE :
40
52
return
@@ -47,40 +59,56 @@ func _physics_process(delta: float) -> void:
47
59
move_and_slide (velocity )
48
60
49
61
62
+ # This is the function that handles combos. It appends attacks to the
63
+ # _combo_current array and, if it finds a matching combo, plays the
64
+ # corresponding attack animation.
50
65
func _attack (attack_type : int ) -> void :
51
66
assert (
52
67
attack_type in [LIGHT_ATTACK , HEAVY_ATTACK ],
53
68
"Unsupported attack type, please use an attack type from the enum."
54
69
)
55
70
71
+ # We don't want to accept another attack until the attack animation allows
72
+ # it.
56
73
accept_next_attack = false
57
74
58
- _combo_current .append (attack_type )
59
75
_state = States .ATTACK
76
+ _combo_current .append (attack_type )
60
77
61
- _animation_player .stop ()
62
-
78
+ # We check every attack of the current combo against every attack of every
79
+ # combo in the COMBOS data structure until we find a match.
80
+ #
81
+ # If we have a match, we assign the next attack's animation to the variable
82
+ # below, which tells us if we should continue or end the combo.
63
83
var next_attack_animation := ""
64
84
var current_attack_count := _combo_current .size ()
65
85
for combo in COMBOS :
86
+ # To avoid indexing errors, we skip any combo shorter than the current combo.
66
87
if current_attack_count > combo .size ():
67
88
continue
68
89
90
+ # We compare each value in the current combo with the values in our
91
+ # reference combo. If any one value doesn't match, then we skip to the
92
+ # next combo.
69
93
var is_match := true
70
94
for index in current_attack_count :
71
95
if _combo_current [index ] != combo [index ]:
72
96
is_match = false
73
97
break
74
98
99
+ # If the current combo matches the reference combo, we store the
100
+ # animation to play next.
75
101
if is_match :
76
- next_attack_animation = COMBOS [combo ][current_attack_count - 1 ]
102
+ next_attack_animation = COMBOS [combo ][current_attack_count - 1 ]. animation
77
103
78
104
if next_attack_animation :
79
105
_animation_player .play (next_attack_animation )
80
106
else :
81
107
_end_combo ()
82
108
83
109
110
+ # This function resets all combo-related variables, to allow the player to start
111
+ # another combo.
84
112
func _end_combo () -> void :
85
113
_state = States .MOVE
86
114
_animation_player .play ("idle" )
0 commit comments