Animation stuck on first frame

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By WimpyBaby

Quite new to godot and Im trying to learn how to program basic movement in a 2D platformer with animated sprites. The animations for moving left, moving right and idle:ing all function without problems. I think that the animation is indeed playing but keeps getting replayed constantly which freezes the frame.

code:

func _physics_process(delta):
motion.y += get_gravity() * delta

if Input.is_action_pressed("ui_right"):
	motion.x = max_speed
	$AnimatedSprite.flip_h = false
	$AnimatedSprite.play("Run")

elif Input.is_action_pressed("ui_left"):
	motion.x = -max_speed
	$AnimatedSprite.flip_h = true
	$AnimatedSprite.play("Run")
	
else:
	motion.x = 0
	$AnimatedSprite.play("Idle")

if Input.is_action_pressed("ui_up"):
	if on_ground == true:
		motion.y = JUMP_HEIGHT

if is_on_floor():
	on_ground = true
	if Input.is_action_just_pressed("ui_up"):
		motion.y = JUMP_VELOCITY
		on_ground = false
else:
	if motion.y < 0:
		$AnimatedSprite.play("Jump")
		print("jumping")
	else:
		on_ground == true
		$AnimatedSprite.play("Fall")
		

motion = move_and_slide(motion, UP)
print(motion)
pass

func get_gravity() -> float:
return JUMP_GRAVITY if motion.y < 0.0 else FALL_GRAVITY

I have tried multiple approaches to playing the falling and jumping animation with little to no success.

Thanks in advance

:bust_in_silhouette: Reply From: Gluon

I think your problem is you are running the animation every time you put in an input. So it restarts every time it registers a keypress. Below is an example where there is a separate function for the animation, now the animation is separated from the input so it should work based on the motion instead.

func _physics_process(delta):
    motion.y += get_gravity() * delta

    if Input.is_action_pressed("ui_right"):
        motion.x = max_speed
    elif Input.is_action_pressed("ui_left"):
        motion.x = -max_speed
    else:
        motion.x = 0

    if Input.is_action_pressed("ui_up"):
        if on_ground == true:
            motion.y = JUMP_HEIGHT

    if is_on_floor():
        on_ground = true
        if Input.is_action_just_pressed("ui_up"):
            motion.y = JUMP_VELOCITY
            on_ground = false
        else:
            on_ground == true


    motion = move_and_slide(motion, UP)
    Animation_Player(motion)

func Animation_Player(motion)
    if motion.y <0:
        $AnimatedSprite.play("Jump")
    elif motion.y >0:
        $AnimatedSprite.play("Fall")
    elif motion.x >0:
        $AnimatedSprite.flip_h = false
        $AnimatedSprite.play("Run")
    elif motion.x < 0:
        $AnimatedSprite.flip_h = true
        $AnimatedSprite.play("Run")
    else:
        $AnimatedSprite.play("Idle")

Worked nicely, thanks :slight_smile:

WimpyBaby | 2022-02-17 20:18

you also can put the controls in another custom function to keep the main process function cleaner.

func _physics_process(delta):
    motion.y += get_gravity() * delta
    check_controls()
    motion = move_and_slide(motion, UP)
    Animation_Player()

so the custom function check_controls() can contain the lines, that it replaces here.

and it looks like in this situation it´s not needed to pass motion to the animations-function, because it´s declared above all functions (it´s not declared inside process here) and can directly be used inside the animations-function

Drachenbauer | 2022-04-17 13:57