2D Grid based movement animation question

Godot Version

v4.3 Stable Win64

Question

Hello, I am brand new to godot and am struggling to find info on this topic. I have a 2D grid based movement setup that is working great, and I drew some sprites with 2 frame walk animations. The issue I’m having is that while the sprite is moving around the grid, I can change which version of the sprite animation is displayed by pressing a different key. The sprite moves in the correct direction and doesn’t change it’s course mid-movement, but I can make it moonwalk. How do you lock the sprite’s animation until it has reached it’s destination?

If you are using an animated sprite for it, then turn on the loop and play it until the player reaches the target, then you can stop the animation.

1 Like

Okay cool, can anyone go into detail on how to do that? If it helps, this is the script I’m currently using.

extends AnimatedSprite2D

func _input(event):

if Input.is_action_pressed("ui_right"):
	play("Right")
elif Input.is_action_pressed("ui_left"):
	play("Left")
elif Input.is_action_pressed("ui_up"):
	play("Back")
elif Input.is_action_pressed("ui_down"):
	play("Front")
1 Like

i’m having a hard time understanding the problem and imagining the moonwalk (and understanding why moonwalking is bad because i tried so hard in junior high to learn how to do it)

Is the question just “how do i know when the animation is finished so that i don’t do anything until it does”? If so, wait for the animation finished signal to get fired or check is_playing().

Here’s a question like that:

I thought it might be easier to show with a video but I guess because I’m new I can’t share attachments. I’ll try to explain in more detail.

I’m trying to make a little game in the style of the old Sega Genesis game Shining Force. In this game, each character has an animation for up, down, left, and right. When the character is not in motion, they continue to face the direction they last moved. The walking animation also serves as the idle animation, giving the effect that the character is marching in place. To this effect, I don’t want the animation to stop and the animation isn’t really synched up to the character’s movement.

Right now, when the player hits a directional key, two things happen that are handled by separate scripts. The script on the CharacterBody2D handles moving the sprite, and that script is able to look at the player’s movement and prevent further input until the sprite arrives on the destination tile.

Separately, the script above controls just which animation is playing, and is not able to determine if the character is in motion. So if I press Left, the animation “Left” starts playing, but while the character is in motion I can press right, causing the animation “Right” to play while the character continues to move left. I have tried to implement things that will lock the character into the correct animation but am having trouble.

I hope this was a bit more clear and I apologize for not understanding as I’m very new to all of this. In case it’s helpful, I’ll also post the script that moves the CharacterBody2D. It might be super messy and have redundancy but it’s working as intended.

extends CharacterBody2D

var target_position = Vector2(0, 0)
var speed = 200
var min_bound = Vector2(-320, -320)
var max_bound = Vector2(320, 320)
var is_moving = false

func _ready():
target_position = self.position

func _process(delta):
position = position.move_toward(target_position, speed * delta)

#Checks if player is standing still
if position == target_position:
is_moving = false

func _input(event):
#denies inputs while the player is moving
if is_moving:
return

var direction = Vector2.ZERO

if Input.is_action_pressed("ui_right"):
	direction.x += 1
elif Input.is_action_pressed("ui_left"):
	direction.x -= 1
elif Input.is_action_pressed("ui_up"):
	direction.y -= 1
elif Input.is_action_pressed("ui_down"):
	direction.y += 1

# Move and check bounds
if direction != Vector2.ZERO:
	var new_target_position = target_position + direction * 32

#Prevents player from leaving set boundaries
if new_target_position.x >= min_bound.x and new_target_position.x <= max_bound.x:
target_position.x = new_target_position.x
if new_target_position.y >= min_bound.y and new_target_position.y <= max_bound.y:
target_position.y = new_target_position.y

	target_position.x = round(target_position.x / 32) * 32
	target_position.y = round(target_position.y / 32) * 32

	is_moving = true

if event.is_action_released("ui_right") or event.is_action_released("ui_left"):
	target_position.y = round(target_position.y / 32) * 32  # Keep Y aligned
if event.is_action_released("ui_up") or event.is_action_released("ui_down"):
	target_position.x = round(target_position.x / 32) * 32  # Keep X aligned