03 Top Down Animated Player - CoderDojo-Ennis/ScratchyGodot GitHub Wiki

Documentation

Godot 4 ARPG Tutorial by Maker Tech Videos 1-3

Godot Documentation

Walkthrough

walkcrop

⚒️ Setup

This GIT repository has an example project, full of game assets to get you started. We'll download it and install it as a Godot project.

  1. Download the source code from this project's GIT repository

  2. Save it somewhere that's easy to get to and remember. Something like C:\Godot\

  3. Open Godot and press the image button on the top right

  4. Press the Browse button next to the Project Path Select the zip file that you saved above

  5. Press the Browse button next to the Project Installation Path and use the Create Folder button and enter the name scratchy, and then press Select Current Folder

  6. Press Import and Edit

    image

🚶 Player Prefab

  1. Open the scene 03-PlayerMovement/PlayerMovement.tscn

  2. Open the 2D view image and you should see a blank stage background.

  3. In the Scene panel, right-click and Add Child Node

    image

    and for the Node Type select CharacterBody2D. You can ignore the yellow warning triangle next to the node for now. But press F2 on the node (or right-click and select rename) and change the "CharacterBody2D" to "Player"

  4. Convert the player node to a Prefab Scene by right-clicking the node and selecting *Save Branch as Scene". This will let us edit the player object in isolation, and potentially add more than one of them into the main scene (stage). Click the Edit Scene button to begin editing the Player prefab scene. image

  5. Right-click the Player node and add a child node with the type Sprite 2D

  6. In the Inspector panel click on the Texture dropdown and choose Quick Load and search for "walk" and choose one of the NinjaAdventure characters

  7. In the Inspector panel Animation section change the HFrames to 4 since the sprite sheet has 4 columns. And set VFrames to 4 for the 4 rows.

    You should now see one of the 16 sprite frames in the 2D view.

    image

▶️ Player Movement

Time for some code!

  1. In the Player prefab scene right click the root "Player" node and choose Attach Node Script. In Godot, each node can have one script. By default it will create a script based on the type of node you have selected. In this case it's a CharacterBody2D node, so it's going to create a character basic movement script. Press Create to accept this.

  2. The code editor will open with the default script already in place. Unfortunately this won't do us any good. The default Godot player script is for a side scrolling platformer character, not a top-down character. So delete all of the code except for the first line. The top line says extends CharacterBody2D This indicates the type of node the script is attached to.

  3. Our code is going to have 2 functions. The _ready function runs when the Player prefab is added to the stage. And the _physics_process function runs 30 times per second. This is how they compare to a scratch script:

    image

    extends CharacterBody2D
    
    func _ready():
        pass
    
    func _physics_process(delta):
        pass
    
  4. We'll make a function to process the keyboard input and move the player. We'll also need to declare a Speed variable for the movement, and in the _physics_process() function we'll call the input function, and then call move_and_slide() to let the physics engine do it's job. When we add these to our script it should look like this:

    extends CharacterBody2D
    
    @export var speed: float = 50
    
    func _ready():
        pass
    
    func _physics_process(delta):
        handleInput()
        move_and_slide()
    
    func handleInput():
        var moveDirection: Vector2 = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
        velocity = moveDirection * speed
    

    If you play the PlayerMovement (stage) scene, you can move your player using the arrow keys with the stage background. But they're just sliding around. We'll animate in the next step.

➡️ Create Directional Walk Animations

  1. In the Player prefab scene (without the stage background), right click the Player root node and add a child with the type AnimationPlayer the same as we did last week in *02 Animation Player"

  2. We'll create 4 animations. One for each of our walk directions. And each will have 4 sprite frames. Start by creating an animation by pressing the image button, choosing New and naming it "WalkDown".

  3. On the Snap Seconds input at the bottom right, enter 0.25. Our animation is 1 second long, and we want to have 4 frames in that second. So it's 0.25 seconds per frame.

    image

  4. Select the Sprite2D in the scene, and in the inspector's Animation section click the key next to Frame Coords with X and Y both set to 0. We DONT want bezier curves for spritesheet animations.

  5. Notice that Godot incorrectly changed the X to 1. Change this back to 0, and change the Y value to 1 instead. Press the key again. Repeat this step keeping X at 0 and for Y values up to 3.

  6. You should now see your 4 frames in the animation window. Each spaced 0.25 seconds apart.

  7. Make sure the Looping image button is turned on

  8. Click the Animation button that we used to create the animation, but this time select Duplicate and enter the name "WalkUp"

  9. Click on the 1st frame, and in the Inspector panel change X from 0 to 1. Do the same for the 3 other frames.

  10. Repeat the previous 2 steps for "WalkLeft" and "WalkRight". Use X=2 for the left frames, and X=3 for the right frames

🧭 Play the Correct Directional Animation

  1. Click on the Script button at the top to switch from 2D to Script mode.

  2. At line 4 of the script add this

    @onready var animationPlayer = $AnimationPlayer
    

    This will make it so that our Player node that the script is attached to can interact with the AnimationPlayer inside of it. We use the $ to signify that this is the name of a child node.

  3. Add a function that will play the correct animation based on the player's movement velocity. Like this:

    func updateAnimation():
        if velocity.length() == 0:
            animationPlayer.pause()
        elif velocity.x < 0:
            animationPlayer.play("WalkLeft")
        elif velocity.x > 0:
            animationPlayer.play("WalkRight")
        elif velocity.y < 0:
            animationPlayer.play("WalkUp")
        else:
            animationPlayer.play("WalkDown")
    
  4. Call that function inside the _physics_process function which should now look like this

    func _physics_process(delta):
        handleInput()
        move_and_slide()
        updateAnimation()