Skip to main content

Godot: Single Level 2D Platformer (Part 3) Player Death

This continues from Part 2 but can be completed using Part 1.

We are going to add a Area 2D and sprite to the bottom of the Level1 scene that will be used to detect contact with the player.

If the player touches the Area2D sprite the player will respawn.

Open Level1.

Add an Area2D node to the Level root node. Rename it DeathArea

Add a sprite and CollisionShape2D to the DeathArea

Add an image to the sprite.

Then resize the DeathArea

Add a shape to the CollisionShape2D node. Resize it to cover the death area.

Now we need to add code to manage detecting a collision with this object.

Select the DeathArea Area2D node.

Select the Node tab next to the Inspector.

Double click on body_entered

This will handle if a physics node has entered this area.

We then need to link up the script that contains the object that will collide with / overlap the death area.

In this case it is the Player script.

Open the Player.gd script.

You should see a function at the end of the file that has been added.

This will run when the body enters the DeathArea object

We will test that this works first.

Replace pass with print("Player death") as shown in #23

# 1 Extend the kinematic body node to allow for 2d physics
extends KinematicBody2D

var _path_pos2d = get_node($"../SpawnPoint") # assign from editor

# 2 Create a gravity variable of type int and set it to 800
# In capitals as it is a constant and won't change
var GRAVITY : int = 80

# 3 Create a variable to store the player velocity
# Set this to the type of a 2D vector e.g. x and y
var velocity: Vector2 = Vector2()
# 7 Create a variable to set the speed of the player
# 20 Update the speed that the player moves
var speed : int = 50
# 14 Jump force
var jump : int = 50

# 4 Create a sprite variable and link it to the sprite node. When the node is
# initialised.
onready var sprite = $Sprite
# 21 Add a variable for the audio stream player
onready var audioPlayer = $AudioStreamPlayer2D

# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.


# 5 Runs the physics updates to the game
func _physics_process(delta):
# 6 Update the y axis velocity by the time elapsed
velocity.y += delta * GRAVITY

# 8 Check is the left input is pressed
# note player_left is the action in the input map
if Input.is_action_pressed("player_left"):
# 9 Update the velocity by the speed of the player
# 18 set x velocity to -speed to have fixed speed
velocity.x = -speed
# 10 do the same for the moving right
elif Input.is_action_pressed("player_right"):
# 19 set x velocity to speed to have fixed speed
velocity.x = speed
# 11 If left or right is not pressed set the x velocity to 0
else:
velocity.x = 0

# 12 Flip the sprite depending on the direction of movement
if velocity.x < 0:
sprite.flip_h = false
elif velocity.x > 0:
sprite.flip_h = true

# 15 Detect the jump button being pressed
# 17 Add the is_on_floor() check to the jump condition
if Input.is_action_pressed("player_jump") && is_on_floor():
# 16 Multiply by -1 to turn the velocity into a negative value
velocity.y = jump * -1
# 22 Play the audio for the jump
audioPlayer.play()

# 13 Move the object, the second parameter sets the vertical axis
move_and_slide(velocity, Vector2.UP)

func _on_DeathArea_body_entered(body):
# 23 Test object overlap
print("Player death")

Test your program.

You can see that the object overlap has been detected.

we will keep it simple initially by just reloading the scene.

Add get_tree().reload_current_scene() after the print statement as shown in #24.

# 1 Extend the kinematic body node to allow for 2d physics
extends KinematicBody2D

# 2 Create a gravity variable of type int and set it to 800
# In capitals as it is a constant and won't change
var GRAVITY : int = 80

# 3 Create a variable to store the player velocity
# Set this to the type of a 2D vector e.g. x and y
var velocity: Vector2 = Vector2()
# 7 Create a variable to set the speed of the player
# 20 Update the speed that the player moves
var speed : int = 50
# 14 Jump force
var jump : int = 50

# 4 Create a sprite variable and link it to the sprite node. When the node is
# initialised.
onready var sprite = $Sprite
# 21 Add a variable for the audio stream player
onready var audioPlayer = $AudioStreamPlayer2D

# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.


# 5 Runs the physics updates to the game
func _physics_process(delta):
# 6 Update the y axis velocity by the time elapsed
velocity.y += delta * GRAVITY

# 8 Check is the left input is pressed
# note player_left is the action in the input map
if Input.is_action_pressed("player_left"):
# 9 Update the velocity by the speed of the player
# 18 set x velocity to -speed to have fixed speed
velocity.x = -speed
# 10 do the same for the moving right
elif Input.is_action_pressed("player_right"):
# 19 set x velocity to speed to have fixed speed
velocity.x = speed
# 11 If left or right is not pressed set the x velocity to 0
else:
velocity.x = 0

# 12 Flip the sprite depending on the direction of movement
if velocity.x < 0:
sprite.flip_h = false
elif velocity.x > 0:
sprite.flip_h = true

# 15 Detect the jump button being pressed
# 17 Add the is_on_floor() check to the jump condition
if Input.is_action_pressed("player_jump") && is_on_floor():
# 16 Multiply by -1 to turn the velocity into a negative value
velocity.y = jump * -1
# 22 Play the audio for the jump
audioPlayer.play()

# 13 Move the object, the second parameter sets the vertical axis
move_and_slide(velocity, Vector2.UP)

func _on_DeathArea_body_entered(body):
# 23 Test object overlap
print("Player death")
# 24 Reload the scene
get_tree().reload_current_scene()

Test the scene. You will now notice that when you collide with the DeathArea the scene reloads.

Creating a Spawn Point

Rather than reloading the entire scene if could be useful to spawn the player at a specific location.

Create a Poisition2D node asa child of the root node and position it on the scene where you want the player to respawn.

Rename it SpawnPoint

Open the Player script

Comment out or remove the code you added for # 24

We need to update the player position.

There is a variable named position that is part of the Node2D node.

Add the code as shown in #25 below.

Start with position =

Then drag the Position2D object into the script. This will add a relative reference to the node.

We then use dot notation to get the position of the SpawnPoint using .position

# 1 Extend the kinematic body node to allow for 2d physics
extends KinematicBody2D

# 2 Create a gravity variable of type int and set it to 800
# In capitals as it is a constant and won't change
var GRAVITY : int = 80

# 3 Create a variable to store the player velocity
# Set this to the type of a 2D vector e.g. x and y
var velocity: Vector2 = Vector2()
# 7 Create a variable to set the speed of the player
# 20 Update the speed that the player moves
var speed : int = 50
# 14 Jump force
var jump : int = 50

# 4 Create a sprite variable and link it to the sprite node. When the node is
# initialised.
onready var sprite = $Sprite
# 21 Add a variable for the audio stream player
onready var audioPlayer = $AudioStreamPlayer2D

# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.


# 5 Runs the physics updates to the game
func _physics_process(delta):
# 6 Update the y axis velocity by the time elapsed
velocity.y += delta * GRAVITY

# 8 Check is the left input is pressed
# note player_left is the action in the input map
if Input.is_action_pressed("player_left"):
# 9 Update the velocity by the speed of the player
# 18 set x velocity to -speed to have fixed speed
velocity.x = -speed
# 10 do the same for the moving right
elif Input.is_action_pressed("player_right"):
# 19 set x velocity to speed to have fixed speed
velocity.x = speed
# 11 If left or right is not pressed set the x velocity to 0
else:
velocity.x = 0

# 12 Flip the sprite depending on the direction of movement
if velocity.x < 0:
sprite.flip_h = false
elif velocity.x > 0:
sprite.flip_h = true

# 15 Detect the jump button being pressed
# 17 Add the is_on_floor() check to the jump condition
if Input.is_action_pressed("player_jump") && is_on_floor():
# 16 Multiply by -1 to turn the velocity into a negative value
velocity.y = jump * -1
# 22 Play the audio for the jump
audioPlayer.play()

# 13 Move the object, the second parameter sets the vertical axis
move_and_slide(velocity, Vector2.UP)

func _on_DeathArea_body_entered(body):
# 23 Test object overlap
print("Player death")
# 24 Reload the scene
#get_tree().reload_current_scene()
# 25 Respawn player at location
position = $"../SpawnPoint".position

Test your program, when the player dies they should now respawn at the location you have chosen.