My code is broken and I don't know how to fix it, can anyone help me?

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

Hi everyone!

I’m currently working on a 2D Roguelike to go in my portfolio for university. When I move my sprite vertically the animation freezes. I’ve tried everything I know (which isn’t a lot as I’m still learning), but I just can’t seem to wrap my head around it. Can anyone able to help me out?

file:///home/socks/Pictures/Screenshots/roguelike-code_screenshot.png

Thank you :slight_smile:

Edit: I will try to give everyone more information on what’s going on, I hope this clears things up a bit. I will continue to edit this to show what as been tried

#file:///home/socks/Videos/broken-animation.gif

#Current code
extends KinematicBody2D

const MAX_SPEED = 100
const ACCELERATION = 25

var motion = Vector2()

func _physics_process(delta):

if Input.is_action_pressed("ui_left"):
	motion.x = max(motion.x-ACCELERATION, -MAX_SPEED)
	$AnimatedSprite.flip_h = true
	$AnimatedSprite.play("Run")
elif Input.is_action_pressed("ui_right"):
	motion.x = min(motion.x+ACCELERATION, MAX_SPEED)
	$AnimatedSprite.flip_h = false
	$AnimatedSprite.play("Run")
else:
	$AnimatedSprite.play("Idle")
	motion.x = lerp(motion.x, 0, 0.1)

move_and_slide(motion)
pass

#Removed from “Current code”
if Input.is_action_pressed(“ui_up”):
motion.y = max(motion.y-ACCELERATION, -MAX_SPEED)
$AnimatedSprite.play(“Run”)
elif Input.is_action_pressed(“ui_down”):
motion.y = min(motion.y+ACCELERATION, MAX_SPEED)
$AnimatedSprite.play(“Run”)
else:
motion.y = lerp(motion.y, 0, 0.1)

#What I have tried so far:

#Placing this under my button presses
func _play_animation(direction):
match direction:
“ui_up”:
$AnimatedSprite.play(“Run”)
“ui_down”:
$AnimatedSprite.play(“Run”)

//////////////////////////////
func _play_animation(direction):
match direction:
“ui_up”:
$AnimatedSprite.play(“Run”)
“ui_down”:
$AnimatedSprite.play(“Run”)

:bust_in_silhouette: Reply From: MysteryGM

Is your animation set to looping?

enter image description here
The other animation player also has a looping setting.

If this isn’t your problem can you elaborate on what you have tried. Don’t want to keep tell you to do things you already tried :slight_smile:

My animation is set to looping; I turned it off and It didn’t fix it.

When I said I’ve tried everything I know, I meant that I jumbled around the code in hopes it was something that was misplaced. An example that I’ve been working on in a separate text editor is this:

func _physics_process(delta):

if Input.is_key_pressed(KEY_W):
	motion.y = max(motion.y-ACCELERATION, -MAX_SPEED)
	$Sprite.play("Run")
if Input.is_key_pressed(KEY_A):
	mmotion.x = max(motion.x-ACCELERATION, -MAX_SPEED)
	$Sprite.flip_h = true
	$Sprite.play("Run")
if Input.is_key_pressed(KEY_S):
	motion.y = min(motion.y+ACCELERATION, MAX_SPEED)
	$Sprite.play("Run")
if Input.is_key_pressed(KEY_D):
	motion.x = min(motion.x+ACCELERATION, MAX_SPEED)
	$Sprite.play("Run")
else:
	$Sprite.play("Idle")
	motion.x = lerp(motion.x, 0, 0.1)
	motion.y = lerp(motion.y, 0, 0.1)

move_and_slide(motion)
pass

As opposed to what you see in the screenshot of my original post.

Essentially, what is happening is, I can move left and right and the “$Sprite.play(“Run”)” activates and flips accordingly. If I try try to move up or down with the code you see in the first screenshot, it plays the Idle animation. When I use ^this code^, instead of it playing Idle, it freezes on frame 1 or 2 of the Idle animation and just slides. But I want the Run animation to play in whichever direction the character was facing as they move up or down.

In theory, I wanted the sprite to only be able to look left or right, but have 4 directional movement, if that makes sense?

I hope this helps!

Socks | 2018-10-04 04:51

Hi the problem does appear to be input, like @Ertain mentioned, Godot designed Animation.Play() to be called repeatedly or it pauses.

So in func _process(delta) you need code that animates the sprite all the time.

#Check that the object is moving
if motion != vector2(0,0) :
    $Sprite.play("Run")
else:
    $Sprite.Play("Idle")

This little code should be under your button presses.

MysteryGM | 2018-10-04 16:33

Do you mean like this? my code has been changed slightly, but it’s still essentially the same


extends KinematicBody2D

const MAX_SPEED = 100
const ACCELERATION = 25

var motion = Vector2()

func _physics_process(delta):

if Input.is_action_pressed("ui_left"):
	motion.x = max(motion.x-ACCELERATION, -MAX_SPEED)
	$AnimatedSprite.flip_h = true
	$AnimatedSprite.play("Run")
elif Input.is_action_pressed("ui_right"):
	motion.x = min(motion.x+ACCELERATION, MAX_SPEED)
	$AnimatedSprite.flip_h = false
	$AnimatedSprite.play("Run")
else:
	$AnimatedSprite.play("Idle")
	motion.x = lerp(motion.x, 0, 0.1)
if Input.is_action_pressed("ui_up"):
	motion.y = max(motion.y-ACCELERATION, -MAX_SPEED)
	$AnimatedSprite.flip_h = false
	$AnimatedSprite.play("Run")
elif Input.is_action_pressed("ui_down"):
	motion.y = min(motion.y+ACCELERATION, MAX_SPEED)
	$AnimatedSprite.flip_h = false
	$AnimatedSprite.play("Run")
else:
	$AnimatedSprite.play("Idle")
	motion.y = lerp(motion.y, 0, 0.1)

if motion != Vector2():
	$AnimatedSprite.play("Run")
else:
	$AnimatedSprite.play("Idle")

move_and_slide(motion)
pass

Socks | 2018-10-04 19:03

No.
What I meant was that you should stop placing the animation code under the button press.
If your code looks like this:

if Input.is_key_pressed(KEY_W):
    motion.y = max(motion.y-ACCELERATION, -MAX_SPEED)
    $Sprite.play("Run")
if Input.is_key_pressed(KEY_A):
    mmotion.x = max(motion.x-ACCELERATION, -MAX_SPEED)
    $Sprite.flip_h = true
    $Sprite.play("Run")

Then you need to separate the animation from the buttons:

if Input.is_key_pressed(KEY_W):
    motion.y = max(motion.y-ACCELERATION, -MAX_SPEED)
if Input.is_key_pressed(KEY_A):
    mmotion.x = max(motion.x-ACCELERATION, -MAX_SPEED)

#Check that the object is moving
if motion != vector2(0,0) :
    $Sprite.play("Run")
else:
    $Sprite.Play("Idle")

This way your animation is decided by what is happening with the character, instead of playing while the button is down, now there will be less conflicts.

The problem looks to be in how Godot is treating the inputs, by removing the animation from the direct input it can no longer cause problems.

MysteryGM | 2018-10-04 23:44

I implemented this into my code, it seems to have fixed the animation freezing. However, how do I get my sprite to stop moving in the pressed direction after I release the key?

func _physics_process(delta):

if Input.is_action_pressed("ui_up"):
	motion.y = max(motion.y-ACCELERATION, -MAX_SPEED)
if Input.is_action_pressed("ui_left"):
	motion.x = max(motion.x-ACCELERATION, -MAX_SPEED)
	$AnimatedSprite.flip_h = true
if Input.is_action_pressed("ui_down"):
	motion.y = min(motion.y+ACCELERATION, MAX_SPEED)
if Input.is_action_pressed("ui_right"):
	motion.x = min(motion.x+ACCELERATION, MAX_SPEED)
	$AnimatedSprite.flip_h = false
if motion != Vector2():
	$AnimatedSprite.play("Run")
else:
	$AnimatedSprite.play("Idle")
	motion.x = lerp(motion.x, 0, 0.1)
	motion.y = lerp(motion.y, 0, 0.1)

move_and_slide(motion)
pass

Socks | 2018-10-05 02:23

:bust_in_silhouette: Reply From: Ertain

Could it be in how you’re detecting the inputs? Instead of using Input.is_key_pessed(), maybe it should be Input.is_action_just_pressed()?

Sadly, this didn’t help. It stopped my character from moving at all unless I tap the keys like crazy.

I really appreciate you trying to help me! :slight_smile:

Socks | 2018-10-04 14:46

Then maybe one of the animations keeps getting played? Maybe you should check for whether the currently playing animation is the one you want?

Ertain | 2018-10-04 14:51

How would I go about doing that?

Socks | 2018-10-04 15:49

I don’t know whether this will help, considering my player moves in four directions, but what I use is a combination of Input.is_action_pressed() and an animation function:

# The movement code
var speed = 200
func _get_input():
    velocity = Vector2()
    if Input.is_action_pressed('ui_right'):
        velocity.x += 1
        _play_animation("ui_right")
    if Input.is_action_pressed('ui_left'):
        velocity.x -= 1
        _play_animation("ui_left")
    if Input.is_action_pressed('ui_down'):
        velocity.y += 1
        _play_animation("ui_down")
    if Input.is_action_pressed('ui_up'):
        velocity.y -= 1
        _play_animation("ui_up")
    # The player has stopped moving when the velocity variable has a Vector2 value. Also better check for whether the player's animation is still going.
    if velocity == Vector2() and player.is_playing():
        player.stop()
    velocity = velocity.normalized() * speed

# The animation code
func _play_animation(direction):
    match direction:
        "ui_right":
            player.play("Walking right")
        "ui_left":
            player.play("Walking left")
        "ui_down":
            player.play("Walking down")
        "ui_up":
            player.play("Walking up")
...
# In the _physics_process() function:
func _physics_process(change_in_frame):
    _get_input()
    move_and_slide(velocity)

Ertain | 2018-10-04 18:13

I’m not using velocity in my game, but I tried:


func _play_animation(direction):
match direction:
“ui_up”:
$AnimatedSprite.play(“Run”)
“ui_down”:
$AnimatedSprite.play(“Run”)

Although the code worked, the animation still freezes when it moves up and down. I don’t really have a problem with the direction it’s facing. It’s more so just getting the animation to not freeze when moving vertically.

I’m going to keep trying different parts of your code though, in the hopes it might fix something.

Socks | 2018-10-04 19:15

Hmm, I think I have the same problem in my game, too. :-/ What may be happening is that the engine is detecting a combination of key presses, and keeps playing the start of the animation. I think we should figure out the direction of the player via the vector, and play the proper animation for that direction. How to do this, though, I have not a clue.

Ertain | 2018-10-04 21:05

I’ll keep working on it!

I’m wondering if this is somthing that should be brought to the attention of the developers?

Socks | 2018-10-04 21:24

Not really. Maybe this should be addressed in an official demo, but the engine is functioning as intended.

Ertain | 2018-10-05 01:48