I have a simple 2D top-down game. I want to be able to move my character up down left and right with the directional keys and I want the most recently pressed key to supersede any earlier key being held. I found this code that creates a kind of key press “queue” (array direction_history) and appends the most recently pressed key direction to the “front” of the “queue” while removing earlier elements when a key is released:
const PLAYER_SPEED = 175
const MOVEMENTS = {
'ui_up': Vector2.UP,
'ui_left': Vector2.LEFT,
'ui_right': Vector2.RIGHT,
'ui_down': Vector2.DOWN
var direction_history = []
velocity = Vector2.ZERO
func _process(delta):
for direction in MOVEMENTS.keys():
if Input.is_action_just_released(direction):
var index = direction_history.find(direction)
if index != -1:
direction_history.remove_at(index)
if Input.is_action_just_pressed(direction):
direction_history.append(direction)
if direction_history.size():
var direction = direction_history[direction_history.size() - 1]
velocity = MOVEMENTS[direction]
velocity = velocity.normalized() * PLAYER_SPEED
move_and_collide(velocity * delta)
I’ll be honest, I am kind of a moron and don’t totally understand how this works. If someone can explain it that would be helpful.
Anyway, the real problem is sometimes it bugs out and gets stuck permanently going one direction. I suspect this is because for some reason godot didn’t register a key release and remove_at the previous key entry from the direction_history array. But I don’t understand exactly why this is happening or how to fix it.
Any help would be appreciated! I am also open to alternate code/solutions. Thanks
var velocity=Vector2(0,0)
var PLAYER_SPEED=175
func _process(delta):
if Input.is_action_just_pressed(ui_up):
velocity.y=-PLAYER_SPEED
if Input.is_action_just_pressed(ui_right):
velocity.x=PLAYER_SPEED
if Input.is_action_just_pressed(ui_left):
velocity.x=-PLAYER_SPEED
if Input.is_action_just_pressed(ui_down):
velocity.y=PLAYER_SPEED
Hi, this isn’t working - I want the player to be able to hold down the movement key not have to press them over and over again.
Edit: changed “is_action_just_pressed” to “is_action_pressed” - but the problem now is I do not want diagonal movement. I just want the most recently pressed directional key to supersede whatever was happening before
The reason why yours doesnt work is because first of all you dont call Input.get_vector every frame so your input wont be updated. second of all you call physics-code in the process-method instead of the physics_process method
My last message should be what you are looking for
One additional nuance (more of a nice to have) - when a player presses a second directional key, instead of moving diagonally your code stops the old key entry and prioritizes the new key entry (which is good). If, however, the new key is released, I actually want the direction to go back to the previous key entry that is still being held down. With your function the player just stops moving even though the prior key is still being held down. I suspect that is what the former code I found was trying to accomplish by retaining a queue of key presses.