0 votes

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

Godot version 3.3.3
in Engine by (20 points)

1 Answer

+1 vote
Best answer

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")
by (1,683 points)
selected by

Worked nicely, thanks :)

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

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.