Try out our latest games now! →
iconSUPERMATRIX STUDIO
ProjectsToolsGuidesBlogNewsPlay Now!
iconSUPERMATRIX STUDIO
Play Now!
  • Home
  • Projects
  • Tools
  • About
  • Blogs
  • News

Socials

  • Twitter
  • GitHub
  • LinkedIn

UI Integration, Game Over State, and Score Tracking

UI Integration, Game Over State, and Score Tracking
Instructor

NoFace

Mentor

Welcome to the fourth lesson. We have a flying bird and generating pipes, but there are no consequences or rewards yet. In this module, we will implement collision detection for crashing, track the player's score using custom canvas elements, and build a Game Over loop.


1. Building the User Interface#

To ensure our UI always stays on top of the screen and doesn't scroll with the camera or game world, we use a CanvasLayer.

  1. Open your Main scene.
  2. Add a CanvasLayer node and name it UI.
  3. Add a Control node as a child of UI and set its anchors to "Full Rect" (spanning the whole screen).
  4. Add a Label for the score. Name it ScoreLabel. In the Inspector, under Theme Overrides > Fonts, assign a retro font and set the size to 48. Center it at the top of the screen.
  5. Add a PanelContainer named GameOverScreen containing a "Game Over" Label and a "Restart" Button. Set its visibility to hidden by default.

2. Detecting Crashes#

Our bird needs to know when it hits a pipe or the floor.

  1. Open the Bird scene.
  2. In the _physics_process function, move_and_slide() automatically handles body collisions. We can check if a collision occurred right after calling it.

Update your Bird.gd script:

gdscript
extends CharacterBody2D
class_name Bird

signal crashed

# ... existing variables ...
var is_alive: bool = true

func _physics_process(delta: float) -> void:
	if not is_alive:
		# Just fall if dead
		velocity.y += gravity * delta
		move_and_slide()
		return

	# ... existing gravity and flap logic ...

	move_and_slide()
	
	# Check for collisions with pipes (StaticBody2D)
	for i in get_slide_collision_count():
		var collision = get_slide_collision(i)
		if collision.get_collider() is StaticBody2D:
			die()

func die() -> void:
	is_alive = false
	crashed.emit()

3. Tying it Together: The Game Manager#

Now, let's orchestrate the score, the UI, and the game-over state from our Main.gd script.

  1. In your Main scene, connect the crashed signal from your Bird node to the Main script.
  2. Update Main.gd to handle the score and game over logic.
gdscript
extends Node2D

@onready var score_label: Label = $UI/Control/ScoreLabel
@onready var game_over_screen: PanelContainer = $UI/Control/GameOverScreen
@onready var spawn_timer: Timer = $SpawnTimer
@onready var bird: Bird = $Bird

var score: int = 0

func _ready() -> void:
	# Ensure the background shader moves when we start
	RenderingServer.global_shader_parameter_set("game_speed_multiplier", 1.0)

# ... existing spawn logic ...

func add_score() -> void:
	score += 1
	score_label.text = str(score)

func _on_bird_crashed() -> void:
	# Stop spawning pipes
	spawn_timer.stop()
	
	# Stop the scrolling background shader we created in Lesson 2
	RenderingServer.global_shader_parameter_set("game_speed_multiplier", 0.0)
	
	# Stop existing pipes from moving (assuming pipes check the global multiplier or have a script)
	get_tree().call_group("pipes", "set_process", false)
	
	# Show UI
	game_over_screen.show()

Connecting the Score: Don't forget to connect the scored signal from the ScoreZone Area2D in your pipes to the add_score function in Main.gd when you instantiate them!

4. Restarting the Game#

Finally, connect the pressed signal of your Restart button inside the GameOverScreen to your Main.gd script:

gdscript
func _on_restart_button_pressed() -> void:
	# Reload the current scene to start fresh
	get_tree().reload_current_scene()

You now have a fully playable, scoring, and loopable core gameplay experience!

PreviousProcedural Pipe Generation and Collision DetectionNextGame Polish: Audio, Screen Shake, and Main Menu

Explore More Lessons

Project Setup and 2D Physics Foundation

Completed

Infinite Scrolling Environment with Shaders

Completed

Procedural Pipe Generation and Collision Detection

Completed

UI Integration, Game Over State, and Score Tracking

Current Lesson

Game Polish: Audio, Screen Shake, and Main Menu

Up Next

Supermatrix Studio

Building immersive, neon-drenched worlds.

Social
© 2026 Supermatrix Studio. All rights reserved.