Hello!
I’m trying for the first time to get a coroutine working in my code and unfortunately even after all the tutorials I checked I still don’t understand how they work. It’s for input buffering in fighting games.
func key_buffer(key:String)->bool:
print(key_ready)
if (Input.is_action_just_pressed(key)):
if key_ready[key]:
return true
else:
await key_ready[key] # on if statement just straight up doesn't jump
return true # returns true even if key_ready[key] is false
else:
return false
If it really is some abysmal coding, I’m ready for some tips to make it better
I think they removed coroutine based generators in 4.0. I think you want an array of inputs anyways, for a fighting game it’s good to reference the last few inputs and when they happened. You may want to detect more than two button presses in sequence, that’s where an array will help.
A ring buffer data structure would be best I think, which is formed with an Array. The idea is you allocate a few slots, let’s say the longest input you intend to have is 20 actions, two full circles and 4 buttons pressed, so 20 slots. Then we update the array by looping through it, the 21st action overwrites the first, it’s probably old anyways. We only want to look through the array in reverse order, from the latest input to the oldest.
class BufferedInput:
var input: InputEvent
var time: int
const _MAX_INPUTS = 20
var buffered_inputs: Array[BufferedInput] = []
var buffered_inputs_index: int = 0
func _ready() -> void:
buffered_inputs.resize(_MAX_INPUTS)
func _input(event: InputEvent) -> void:
if is_fighting_game_input(event): # how ever you may define this
# Add a new input to the ring buffer
var new_input = BufferedInput.new()
new_input.input = event
new_input.time = Time.get_ticks_msec()
buffered_inputs[buffered_inputs_index] = new_input
# increment the ring buffer
buffered_inputs_index += 1
# loop around if over 20
buffered_inputs_index %= _MAX_INPUTS
func check_buffered_input(action: String, previous: int = 0, within: int = 500) -> bool:
assert(previous < _MAX_INPUTS, "can't get inputs that far back")
var index_mod: int = (buffered_inputs_index - previous) % _MAX_INPUTS
# determine how long ago the action took place
var current_time := Time.get_ticks_msec()
var time_since_action := current_time - buffered_inputs[index_mod].time
if time_since_action < within:
return buffered_inputs[index_mod].input.is_action(action)
else:
# too old
return false
# as an example, how to get a z input
func did_z_input() -> bool:
var a = check_buffered_input("Forward", 0)
var b = check_buffered_input("Down", 1)
var c = check_buffered_input("Forward", 2)
return a and b and c
There are certainly more quality of life functions to add, but I think this would be a good starting point.