04.eight-way-movement

Moving the character in eight direction

In this lesson, you’ll write code to make the character move in eight directions.

More precisely, the code we’ll write here will allow the player to move freely with a joystick, and in eight directions when using the keyboard.

We’ll first make the character move. Then, in the next lesson, we’ll change its displayed sprite depending on the movement direction.

Until now, you’ve used the _process() function to make something move. In this series, we’ll use the _physics_process() function instead.

Why you need to use _physics_process() for physics objects

Game engines typically give you two functions to update game objects: one for physics objects, and one for everything else.

Our character here is a physics object: a KinematicBody2D. When working with physics objects, you want to use the _physics_process() function instead of _process().

This is because the KinematicBody2D node needs to synchronize with the rest of the physics objects in the game world.

The _physics_process() function executes with a fixed delta value of 1 / 60 of a second by default.

The _process() function, on the other hand, has a constantly changing delta value. It depends on how long Godot takes to calculate one frame.

If your game freezes or slows down, the delta value can expand in size. This can cause game objects that move in _process() to move through walls or the ground.

This cannot happen when using _physics_process() as its delta value is constant.

Moving the character

Let’s see how to move our KinematicBody2D.

Attach a new script to the character. We start by defining a speed constant.

# Notice how we capitalize the constant's name. We do this to distinguish them
# from variable names.
const SPEED := 700.0

Constants are values you give a name, just like variables. However, you cannot change a constant’s value in your code.

Writing the following code will result in an error.

func _ready() -> void:
    SPEED = 800.0

Constants protect you and your teammates against inadvertently changing values that shouldn’t change, so we recommend using constants over variables when possible.

The move_and_slide() function

To move a KinematicBody2D, we want to call its move_and_slide() function.

This function makes characters move, collide with walls, and “slide” a bit when moving along angled terrain or on slopes.

The function takes one required argument: the kinematic body’s velocity.

To calculate the velocity, we multiply a speed by our player’s input direction.

To calculate the input direction vector, we call Input.get_vector(). The Input.get_vector() function takes four input actions as its arguments and calculates a normalized direction vector.

func _physics_process(delta: float) -> void:
    var direction := Input.get_vector("move_left", "move_right", "move_up", "move_down")
    var velocity := direction * SPEED

Back in the first project, To Space And Beyond!, we used Input.get_axis() instead.

The Input.get_axis() function is more versatile, and it allowed us to explain normalizing vectors, which is why we taught it in the first project instead of Input.get_vector().

We can then call the move_and_slide() function, giving it our velocity vector.

func _physics_process(delta: float) -> void:
    # ...
    move_and_slide(velocity)

That’s enough to control the character and make them move if you run the scene.

In the next lesson, we’ll change the sprite depending on the player’s input direction. Later in the series, you’ll see how to set up a level with walls to test collisions.

The code

So far, your script should contain the following code.

extends KinematicBody2D

# Notice how we capitalize the constant's name. We do this to distinguish them
# from variable names.
const SPEED := 700.0

func _physics_process(delta: float) -> void:
    var direction := Input.get_vector("move_left", "move_right", "move_up", "move_down")
    var velocity := direction * SPEED
    move_and_slide(velocity)