Spawning new objects after a timer delay

Godot Version

4.2.1

Question

Hey everyone, I’m trying to create Asteroid in Godot as my first project, and I’m running into some issues with spawning new asteroids. So essentially, I’m trying to bring in +1 more asteroids every time all of the asteroids are destroyed, including the clusters that bigger asteroids created.

To that end, I created Area2D node so I can detect the number of objects in the stage with has_overlapping_bodies(), and when the count is 0, I would emit a signal:

extends Area2D

var game = preload("res://Asteroid_Copy.gd")

signal no_asteroids 

func _physics_process(delta):
	var asteroids_remaining = has_overlapping_bodies()
	if asteroids_remaining == false:
		no_asteroids.emit()

And that signal has been called into the main game scene, like so:

var spawn_number = 1


func spawn_asteroid():
	var new_asteroid = preload("res://Asteroids/asteroid_big.tscn").instantiate()
	%PathFollow2D.progress_ratio = randf()
	new_asteroid.global_position = %PathFollow2D.global_position
	add_child(new_asteroid)


func asteroids_spawn():
	for i in range(spawn_number):
		spawn_asteroid()


func _on_asteroid_detection_no_asteroids():
	print("spawn start")
	spawn_number += 1
	asteroids_spawn()

So I got it working so far, but the issue is, I just can’t seem to put a delay on that spawn function without causing problem. For example, I tried using this code:

func _on_asteroid_detection_no_asteroids():
	const SPAWN_DELAY = 3
	await get_tree().create_timer(SPAWN_DELAY).timeout
	print("spawn start")
	spawn_number += 1
	asteroids_spawn()

But after the timer counts down for 3 seconds, asteroids seems to spawn infinitely, when I would like it to run only once every time there’s no objects on the scene.

I’ve also tried using the built in timer node, but that also had it’s issues; either same problem, or the spawn flat out refuses to run.

I know this must be a simple problem to solve, but I’ve been banging my head on the wall since yesterday trying to figure it out. Doesn’t help that I’m new to coding either.

My guess is that this signal is emitted multiple times causing infinite spawning of asteroids.

With your current setup, you can do this in multiple ways:

  • use a variable to keep track of when the signal has been emitted so it doesn’t check for overlapping bodies again until a new asteroid has been spawned.

  • on overlapping bodies == 0, disable the Area2d and enable it after spawning asteroid.

You could just have a counter of how many asteroids have been added when the scene starts.

And when an asteroid is destroyed just take a number away, and when you get to =0 then just do you code instead.

That way you are not constantly checking for overlapping collisions. Which will repeat multiple times in one frame (probably) .