In this bonus lesson, you’ll learn to restrict the player’s movement to four directions, whether they use a gamepad or the keyboard.
We don’t want to change our character directly here, as we’ll reuse the eight-way movement later.
We want a separate copy of the character scene and script, so we don’t lose any work.
In the FileSystem dock, right-click on the
EightWayMovement.tscn
file and select Duplicate.
Name the new file FourWayMovement.tscn
.
Please do the same for the EightWayMovement.gd
script
file.
You should see the following two files in the
TopDownMovement/
directory.
As we duplicated the EightWayMovement scene, the new scene
still has the EightWayMovement.gd
script attached. We need
to replace it.
Double-click the FourWayMovement.tscn
file to open the
scene, and click and drag FourWayMovement.gd
onto the node.
You can see if the node has the correct script by hovering over the script icon with the mouse.
Click the script icon to open FourWayMovement.gd
.
We mostly need to change how we calculate the player’s input direction.
Instead of using Input.get_vector()
to calculate the
character’s movement direction, we use simpler condition blocks.
Replace the line starting with var direction
with this
new code.
func _physics_process(delta: float) -> void:
var direction := Vector2.ZERO
if Input.is_action_pressed("move_right"):
= 1.0
direction.x elif Input.is_action_pressed("move_left"):
= -1.0
direction.x elif Input.is_action_pressed("move_up"):
= -1.0
direction.y elif Input.is_action_pressed("move_down"):
= 1.0 direction.y
We initialize the direction
variable to a of length 0
. That way, if the
player isn’t pressing any keys, the character won’t move.
We call Input.is_action_pressed()
with the corresponding
input action for each of the four input directions.
If the input is pressed, we set the corresponding vector member
variable to 1.0
or -1.0
.
An x
value of 1.0
will make the character
move right, while -1.0
will make it move left. A
y
value of 1.0
will make the character move
down, and -1.0
will move it up.
Notice how we use a series of elif
blocks. This is how
we ensure the player can only move in one of the four directions at a
time.
The order of the condition blocks also gives some inputs priority
over others. If the player presses both the right and left arrow keys,
the character will move to the right because the first conditional block
tests for the move_right
input.
And that’s all we need to restrict the character’s movement to four directions.
As the character cannot move diagonally, you can remove the extra
mappings from the DIRECTION_TO_FRAME
dictionary.
We won’t need the diagonal textures anymore, so we remove two entries from the dictionary to keep the code relevant.
Your dictionary should look like the following.
const DIRECTION_TO_FRAME := {
0,
Vector2.DOWN: 2,
Vector2.RIGHT: 4,
Vector2.UP: }
It’s a good practice to remove bits of code you don’t need anymore.
Before moving on, we have two exercises for you.
Open the practice Eight-way movement.
Open the practice Four-way movement.
Here’s the complete code listing for
FourWayMovement.gd
.
extends KinematicBody2D
const SPEED := 700.0
const DIRECTION_TO_FRAME := {
0,
Vector2.DOWN: 2,
Vector2.RIGHT: 4,
Vector2.UP:
}
onready var sprite := $Godot
func _physics_process(delta: float) -> void:
var direction := Vector2.ZERO
if Input.is_action_pressed("move_right"):
= 1.0
direction.x elif Input.is_action_pressed("move_left"):
= -1.0
direction.x elif Input.is_action_pressed("move_up"):
= -1.0
direction.y elif Input.is_action_pressed("move_down"):
= 1.0
direction.y move_and_slide(SPEED * direction)
var direction_key := direction.round()
= abs(direction_key.x)
direction_key.x if direction_key in DIRECTION_TO_FRAME:
= DIRECTION_TO_FRAME[direction_key]
sprite.frame = sign(direction.x) == -1 sprite.flip_h