Menu
CoddyTech

Split the Rocks

Part of the Projects section of Coddy's Godot journey. Lesson 18 of 36.

A shot rock should split in two. The rock reports that it broke with signal broken(rock) and broken.emit(self). self is the rock, so the listener knows where it was and how it moved.

spawn_rock connects each new rock with rock.broken.connect(_on_rock_broken), and that function spawns two rocks turned apart:

func _on_rock_broken(rock):
	spawn_rock.call_deferred(rock.position, rock.velocity.rotated(0.8) * 1.5)
	spawn_rock.call_deferred(rock.position, rock.velocity.rotated(-0.8) * 1.5)

The signal arrives while Godot is checking which areas touch. Adding an area then stops the game with Can't change this state while flushing queries. call_deferred runs the call at the end of the frame, when that is safe.

For now every rock splits, so they never run out. Sizes come next.

challenge icon

Challenge

Hard

Make shot rocks split in two.

  1. In rock.gd, add signal broken(rock) and call broken.emit(self) when a bullet hits, before queue_free().
  2. In main.gd, connect each rock's broken to _on_rock_broken in spawn_rock.
  3. In _on_rock_broken(rock), spawn two rocks as shown, with call_deferred.

Press Play and shoot a rock: two rocks fly apart. Then Check.

Try it yourself

extends Node2D

const ROCK = preload("res://rock.tscn")

func _ready():
	for i in 4:
		spawn_rock(Vector2(randf_range(0, 640), 0), Vector2(randf_range(-90, 90), randf_range(40, 90)))

func spawn_rock(where, velocity):
	var rock = ROCK.instantiate()
	rock.position = where
	rock.velocity = velocity
	add_child(rock)

All lessons in Projects

Practice on your own: Godot playground