Godot 3.0 Zelda-like Tutorial [1] Movement and Collision

Player Script

Next we will create the player script. Right click the player node and click Attach Script. Set the template to “empty” and click Create.

First we are going to create a new constant called SPEED. We’ll set this to 70. Then we need a variable called movedir, which will be set to Vector2(0,0). SPEED is self-explanatory, it is how fast the player will be able to move. movedir is the direction the player will attempt to move, depending on the currently pressed keys.

extends KinematicBody2D

const SPEED = 70

var movedir = Vector2(0,0)

We need to create a loop that will set the movedir variable to the direction the player is trying to move. Create a new function called controls_loop(). Inside we will create four new variables, LEFT, RIGHT, UP, and DOWN, and set them to the different UI keys that are included in Godot’s default Input Map.

Underneath these variables we’re going to have two lines of code that set movedir.x and movedir.y to the correct values.

func controls_loop():
	var LEFT = Input.is_action_pressed("ui_left")
	var RIGHT = Input.is_action_pressed("ui_right")
	var UP = Input.is_action_pressed("ui_up")
	var DOWN = Input.is_action_pressed("ui_down")
	
	movedir.x = -int(LEFT) + int(RIGHT)
	movedir.y = -int(UP) + int(DOWN)

This turns the boolean for whether the keys are pressed or not into integers. LEFT and UP are made negative. In the case of movedir.x, if only “ui_left” is pressed, movedir.x will be -1. If only “ui_right” is pressed, movedir.x will be 1. If both are pressed, -1 + 1 will equal 0 and there will be no movement. It works the same way with movedir.y.

The script will now pick up what inputs are being pressed, but it does not yet move the player. Create a new function called movement_loop(). We will make a new variable called motion and set it to movedir.normalized() * SPEED. normalized() takes a Vector2 and makes diagonal movements equal the same distance as cardinal movements. Without that, moving diagonally will be faster than walking straight up or straight right for example. We then multiply that by our SPEED constant, making motion the position the KinematicBody2D will attempt to move.

Underneath, we’ll use move_and_slide(motion, Vector2(0,0)). This function will move the body towards our motion value, and if it collides with a wall, the body will slide against it.

func movement_loop():
	var motion = movedir.normalized() * SPEED
	move_and_slide(motion, Vector2(0,0))

Now we just need to add these loops to the physics process. Put in the _physics_process(delta) function and run our two new functions under it.

func _physics_process(delta):
	controls_loop()
	movement_loop()

If we press F6 and run our player scene we are able to move in eight directions. We cannot yet collide with any walls because there aren’t any, so let’s close off this tutorial with that.