All lessons
Lesson 05

Shooting Bullets

Click to fire. Every bullet is a brand-new copy of a saved scene, created the instant you press the button.

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

This lesson builds new nodes while the game runs. Every bullet is a fresh copy of bullet.tscn, made the instant you click.

The scenes

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

shooting_bullets.tscn
  • ShootingBullets Node2D shooting_bullets.gd
  • ShooterPlayer CharacterBody2D player.tscn
  • EnemyTarget1 StaticBody2D enemy_target.tscn
  • EnemyTarget2 StaticBody2D enemy_target.tscn
  • EnemyTarget3 StaticBody2D enemy_target.tscn
  • EnemyTarget4 StaticBody2D enemy_target.tscn
  • HUD CanvasLayer % hud.tscn
bullet.tscn
  • Bullet Area2D bullet.gd
  • ColorRect
  • CollisionShape2D
enemy_target.tscn
  • EnemyTarget StaticBody2D enemy_target.gd
  • ColorRect
  • CollisionShape2D
hud.tscn
  • HUD CanvasLayer hud.gd
  • MarginContainer
  • ScoreLabel Label %
  • HomeButton Button %
player.tscn
  • ShooterPlayer CharacterBody2D player.gd
  • Body Sprite2D
  • Gun ColorRect
  • Muzzle Marker2D %
  • ShootTimer Timer %
  • CollisionShape2D
extends Node2D

# How many targets are in this level. Counted in "_ready()" below.
var total_targets: int = 0

func _ready() -> void:
	# "get_children()" hands back every node sitting directly under this one.
	# We walk that list and pick out only the targets.
	for child in get_children():
		if child is EnemyTarget:
			total_targets += 1
			# "destroyed" is a LOCAL signal, written inside enemy_target.gd.
			# We can connect to it because each target is our own child, so
			# we can reach it. game_events.gd explains when to use which.
			child.destroyed.connect(_on_target_destroyed)
	# HUD is our child too, so we skip signals and just call its function.
	%HUD.set_total(total_targets)

# Runs when any one target emits "destroyed".
func _on_target_destroyed() -> void:
	# hud.gd connects to "target_destroyed" and moves the counter up.
	GameEvents.target_destroyed.emit()