Lesson 11

Lives System

Fall in a pit, lose a life, reappear at the start. Run out of lives and it is game over.

Loading the game engine. This takes a moment the first time.

Perspective

HOW ONE FALL BECOMES GAME OVER

  1. The player touches a kill zone.
  2. kill_zone.gd emits life_lost AND calls body.respawn().
  3. THIS FILE connects to life_lost, subtracts one, and emits lives_updated so the HUD can redraw.
  4. If lives hit 0, this file also emits player_died.

One signal leads to another. That is called a chain.

The scenes

■ UI node · ■ 2D node · % unique name · .tscn instanced scene

game.tscn
  • Game Node2D game.gd
  • Player CharacterBody2D player.tscn
  • KillZone1 Area2D kill_zone.tscn
  • KillZone2 Area2D kill_zone.tscn
  • KillZone3 Area2D kill_zone.tscn
  • HUD CanvasLayer hud.tscn
hud.tscn
  • HUD CanvasLayer hud.gd
  • MarginContainer
  • LivesLabel Label %
kill_zone.tscn
  • KillZone Area2D kill_zone.gd
  • Polygon2D
  • CollisionShape2D
player.tscn
  • Player CharacterBody2D group: Player player.gd
  • Sprite2D
  • CollisionShape2D

FileSystem

  • game.tscn
  • game.gd
  • hud.tscn
  • hud.gd
  • kill_zone.tscn
  • kill_zone.gd
  • player.tscn
  • player.gd

game_events.gd

Switch it on once, under Project > Project Settings, on the Globals tab. Not made yet? Press Create Script to make it right there. Already made it? Press Select Script/Scene, pick it, and press Add. Its Name column should say GameEvents, which Godot fills in for you. That's the name your code uses.

The code

Perspective
extends Node2D

## How many lives the player begins with.
@export var starting_lives: int = 3

# How many lives are left right now. "_ready()" fills it in.
var lives: int

func _ready() -> void:
	lives = starting_lives
	# kill_zone.gd emits "life_lost". We put "_on_life_lost" inside
	# ".connect()". That is the function Godot runs when it arrives.
	GameEvents.life_lost.connect(_on_life_lost)

func _on_life_lost() -> void:
	lives -= 1
	# hud.gd connects to "lives_updated" and redraws the number.
	GameEvents.lives_updated.emit(lives)
	if lives <= 0:
		# hud.gd connects to "player_died" too, and shows Game Over.
		GameEvents.player_died.emit()