I am trying to add a feature that allows the player to input an attack while their character is going through an animation and have that attack come out as soon as the animation ends.
These are the relevant functions:
signal attack_event(attack)
signal buffer(bufferedAttack)
func _process(delta):
var frame_format = "frame = %s."
var framePrint = frame_format % _animated_sprite.get_frame()
var buffered_format = "%s is buffered"
var bufferedPrint = buffered_format % Global.buffered
var last_frame = _animated_sprite.frames.get_frame_count(_animated_sprite.animation) - 1
if last_frame == _animated_sprite.get_frame() && Global.buffered == "":
print("last frame detected")
emit_signal("buffer", "")
# uppercut
if Input.is_action_just_pressed("light_attack") && Input.is_action_pressed("down") && _animated_sprite.get_frame() > 3:
Global.buffered = "ucut"
print("buffered ucut input received")
elif last_frame == _animated_sprite.get_frame() && Global.buffered == "ucut":
print("buffered ucut confirmed")
Global.buffered = "ucut"
emit_signal("buffer", "ucut")
# jab
if Input.is_action_just_pressed("light_attack") && !Input.is_action_pressed("down") && !Input.is_action_pressed("back") && _animated_sprite.get_frame() > 3:
Global.buffered = "jab"
print("buffered jab input received")
last_frame = _animated_sprite.frames.get_frame_count(_animated_sprite.animation) - 1
elif last_frame == _animated_sprite.get_frame() && Global.buffered == "jab":
print("buffered jab confirmed")
Global.buffered = "jab"
emit_signal("buffer", "jab")
func _input(event):
if event.is_action_pressed("light_attack") && !Input.is_action_pressed("down") && !Input.is_action_pressed("back") && !_animated_sprite.is_playing():
emit_signal("attack_event", "jab")
print("normal jab input received")
elif event.is_action_pressed("light_attack") && Input.is_action_pressed("down") && !_animated_sprite.is_playing():
emit_signal("attack_event", "ucut")
print("normal ucut input received")
func attack_end(bufferedAttack):
if Global.buffered == "" && bufferedAttack == "":
print("ending")
_animated_sprite.stop()
_animated_sprite.frame = 0
set_physics_process(true)
elif Global.buffered == "ucut":
print("ucut signal")
emit_signal("attack_event", "ucut")
elif Global.buffered == "jab":
print("jab signal")
emit_signal("attack_event", "jab")
func attack_handler(attack):
if attack == "jab":
print("jab attack")
_animated_sprite.play("jab")
Global.buffered = ""
set_physics_process(false)
elif attack == "ucut":
print("uppercut attack")
_animated_sprite.play("ucut")
Global.buffered = ""
set_physics_process(false)
The attack_event signal connects to the attack_handler function, the bufferedAttack signal connects to the attack_end function. There's also an autoloaded global script that just declares the "buffered" variable.
The "ucut" attack works as intended, it's possible to buffer it while either the "jab" or the "ucut" animation are playing. The "jab" attack can only be buffered while the "ucut" animation is playing, if the player attempts to buffer it while the "jab" animation is playing, the attack_handler function is called and erases the Global.buffered value as usual, but the "last frame detected" conditional activates and interrupts the buffered animation's start, despite the fact that attack_handler should have already started playing the new animation, making "last frame detected" false.
Here are console logs for several cases (buffering uppercut during uppercut, buffering jab during jab, buffering jab during uppercut) to illustrate:
I have found that rewriting the _process(delta) function to something like this makes both "ucut" and "jab" unbufferable during their own animations, but bufferable during the other attack's animation, so this issue must be related to conditional order, but I can't come up with anything better than what I have at the moment.
func _process(delta):
var last_frame = _animated_sprite.frames.get_frame_count(_animated_sprite.animation) - 1
# ucut
if Input.is_action_just_pressed("light_attack") && Input.is_action_pressed("down") && _animated_sprite.get_frame() > 3:
Global.buffered = "ucut"
print("buffered ucut input received")
elif last_frame == _animated_sprite.get_frame() && Global.buffered == "ucut":
print("buffered ucut confirmed")
Global.buffered = "ucut"
emit_signal("buffer", "ucut")
elif last_frame == _animated_sprite.get_frame() && Global.buffered == "":
print("last frame detected")
emit_signal("buffer", "")
# jab
if Input.is_action_just_pressed("light_attack") && !Input.is_action_pressed("down") && !Input.is_action_pressed("back") && _animated_sprite.get_frame() > 3:
Global.buffered = "jab"
print("buffered jab input received")
last_frame = _animated_sprite.frames.get_frame_count(_animated_sprite.animation) - 1
elif last_frame == _animated_sprite.get_frame() && Global.buffered == "jab":
print("buffered jab confirmed")
Global.buffered = "jab"
emit_signal("buffer", "jab")
elif last_frame == _animated_sprite.get_frame() && Global.buffered == "":
print("last frame detected")
emit_signal("buffer", "")