Sprite animation occurs after movement stops.

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By vicguedez
:warning: Old Version Published before Godot 3 was released.

Hello guys, I’m new to Godot and game developing in general. So I’m trying to integrate state machine pattern into my player, by now the script looks like this:

#Player
extends KinematicBody2D

const STATE_IDLE = 0

onready var State = PlayerIdleState.new(self)

func _ready():
	set_fixed_process(true)

func _fixed_process(delta):
	State.update(delta)

func set_state(new_state):
	State.exit()
	
	if new_state == STATE_IDLE:
		State = PlayerIdleState.new(self)

func get_state():
	if State extends PlayerIdleState:
		return STATE_IDLE

# ------------------------------------------------------------------
class PlayerState:
	
	var Player
	
	func move_player(speed, direction):
		Player.move(direction.normalized() * speed)

# ------------------------------------------------------------------
class PlayerIdleState extends PlayerState:
	
	var speed = 2
	var speed_diagonal_ratio = 1.4
	var current_animation = ""
	
	func movePlayer():
		var motion_speed = speed
		var moving_up = Input.is_action_pressed("player_move_up")
		var moving_right = Input.is_action_pressed("player_move_right")
		var moving_down = Input.is_action_pressed("player_move_down")
		var moving_left = Input.is_action_pressed("player_move_left")
		
		if ((moving_left or moving_right) and (moving_down or moving_up)):
			motion_speed = speed / speed_diagonal_ratio
		
		if moving_up :
			.move_player(motion_speed, Vector2(0, -1))
		elif moving_right:
			.move_player(motion_speed, Vector2(1, 0))
		elif moving_down:
			.move_player(motion_speed, Vector2(0, 1))
			Player.get_node("AnimationPlayer").play("WalkDown")
		elif moving_left:
			move_player(motion_speed, Vector2(-1, 0))
	
	func _init(player):
		Player = player
	
	func update(delta):
		movePlayer()
	
	func input(event):
		pass
	
	func exit():
		pass

I’m having a problem, If I tap my move down key (“S”) it goes down a bit and then plays the animation walking down. If I keep pressed the move down key for lets say 3 seconds, it moves down all that time but doesnt play the animation until it stops moving. Why is that?

Furthermore how can I improve this script? I want to have more states, its a survival game so I will have states like fighting, searching through stuff and etc…

:bust_in_silhouette: Reply From: Warlaan

It’s because you keep restarting the animation every frame, so you only see the first frame until you release the key.

Hello, thanks. That seems logic, but how can fix that?

vicguedez | 2016-11-16 13:31

Use get_current_animation() to get the name of the currently running animation (if any).
AnimationPlayer — Godot Engine (stable) documentation in English

Start the new animation only if its name is different from the name of the animation that is currently running.

Warlaan | 2016-11-16 14:03

:bust_in_silhouette: Reply From: rredesigns

This could be easily fixed with a state var. I did this a couple of times, is fairly easy:

var playing = false #this outside of any loop!
var anim = get_node("AnimationPlayer")

    func _fixed_process(delta):
    
    if Input.is_action_pressed("forward"):
        #Player code here
        if playing == false:       
            anim.play("walk")
            playing = true
        playing = false # Never forget to restore the state!