How can I make my player face in the direction pressed even when they are against a wall?

biskwikmanbiskwikman Posts: 2Member

I currently have it set up so the player sprite plays an animation depending on which direction they are moving in. However this makes it so that when the player is abutting wall (in this case a CollisionShape2d) and the direction towards that wall is pressed, the character does not face in that direction as no animation is played because there is no player movement.

I'm looking at trying to set the first frame of the animation on "is_action_just_pressed()" but I don't understand how to access a single frame from AnimatedSprite node.


Tags :

Answers

  • TwistedTwiglegTwistedTwigleg Posts: 1,716Admin

    You probably need to store a Vector2 with the inputs retrieved from the player, and then use that to set the animation instead of the player movement/velocity. Something like this should work (untested):

    extends KinematicBody2D
    var velocity = Vector2.ZERO
    var input_vector = Vector2.ZERO
    const MOVE_SPEED = 42
    
    func _process(delta):
        # When retrieving input for moving the player, also set input_vector
        if (Input.is_action_pressed("ui_right")):
            velocity.x += MOVE_SPEED * delta
            input_vector.x = 1
        elif (Input.is_action_pressed("ui_left")):
            velocity.x -= MOVE_SPEED * delta
            input_vector.x = -1
        else:
            input_vector.x = 0
        if (Input.is_action_pressed("ui_up")):
            velocity.y += MOVE_SPEED * delta
            input_vector.y = 1
        elif (Input.is_action_pressed("ui_down")):
            velocity.y -= MOVE_SPEED * delta
            input_vector.y = -1
        else:
            input_vector.y = 0
    
        # Move the player
        velocity = move_and_slide(velocity)
    
        # Change animations based on the value stored in input_velocity
        if (input_vector.y >= 1):
            if (input_vector.x >= 1):
                $AnimatedSprite.play("walk_up_right")
            elif (input_vector.x <= -1):
                $AnimatedSprite.play("walk_up_left")
            else:
                $AnimatedSprite.play("walk_up")
        elif (input_vector.y <= -1):
            if (input_vector.x >= 1):
                $AnimatedSprite.play("walk_down_right")
            elif (input_vector.x <= -1):
                $AnimatedSprite.play("walk_down_left")
            else:
                $AnimatedSprite.play("walk_down")
        else:
            if (input_vector.x >= 1):
                $AnimatedSprite.play("walk_right")
            elif (input_vector.x <= -1):
                $AnimatedSprite.play("walk_left")
            else:
                $AnimatedSprite.play("idle")
    

    This is similar to the method I described in this topic for alternating user input for an AnimatedSprite3D node. The main idea is to use a Vector2 that represents the direction the player wants to move towards rather than the direction the player is actually moving. That way, the player will always be looking towards the direction of the input from the player.


    For setting the AnimatedSprite frame, I think you can just change the frame property of the AnimatedSprite (documentation) to the frame you want to show.
    That said, I haven't really used the AnimatedSprite node very much, so I might be missing something.


    Hopefully this helps!
    (Side note: Welcome to the forums!)

  • biskwikmanbiskwikman Posts: 2Member

    Thanks a lot for your detailed response! I'll try to implement this over this weekend and post back my progress.
    (Happy to be here! I'm loving Godot so far.)

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file