spawn enemies randomly every 10 seconds, but it will only spawn them once !

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Rashid

Hi i am making a 2d platformer, and my issue is that the spawn will work after the time out which is 10 seconds but after i shoot all of the enemies, there will be no enemies respawning again

hierarchy:timer spawn - Album on Imgur

here is my code

func _on_Timer_timeout():
var Enemy = load ("res://Enemies/bat.tscn")
var player =$Bat
var e = Enemy.instance()
var pos = player.position
if randf() < 0.5: 
	# On the left
	pos.x -= rand_range(50.0, 200.0)
else:
	# On the right
	pos.x += rand_range(50.0, 200.0)
e.position = pos # the enemy position will be randomly either on left or right
add_child(e) 	# add child to scene!

To which node in the tree is your script attached? In the screenshot you provided there is no node called “Bat”, only “bat” - but node names are case-sensitive! Also the parent node of “bat” is “background” which doesn’t have a script attached.

Have you ensured that:

  • … the timer is actually started? (manually or via setting “Autostart” to true)
  • … the callback is connected properly? (print something or use a breakpoint)
  • … the timer’s “Oneshot”-property is disabled?

njamster | 2020-07-18 17:08

sorry! i connected the timer to bat, and yes the “Oneshot”-property is disabled. i noticed that since i have two bats instances if i killed them before the timer, they wont spawn even after the timer.

Also if i killed the orignal instance all of the spawned ones will dissapear!

Here is my code when the bat dies:

func _on_stats_no_health():
	spawner(1)
	$Bat.play("death") #receives the no health signal and die
	yield($Bat, "animation_finished") #wait for animation to fully finish and queue free
	queue_free()

Rashid | 2020-07-18 17:28

I connected the timer to bat

Do you mean the script (with the _on_Timer_timeout-callback) is attached to the Bat-node? If so, then yes, freeing the Bat-node will remove the callback as well, thus no new Bats will be spawned once all Bats are gone (as then script is gone too).

Also if i killed the orignal instance all of the spawned ones will dissapear!

That shouldn’t happen! Instances are independent of each other, even if they are both based on the same scene. Freeing one bat instance won’t free all other bats!

Here is my code when the bat dies

I assume the “death”-animation is purely visual. But what does spawner(1) do?

njamster | 2020-07-18 18:10

Really appreciate your reply. Yes i connected it to the bat node in the imgur.

the spawner(1) is supposed to spawn another bat once it dies!

i did some research and i am afraid i am losing all of the bats because of the queue free?

Here is my code for reference!:
the _on_stats_no_health() will be called by a signal when health <=0

func _on_Hurtbox_body_shape_entered(body_id, body, body_shape, area_shape):
stats.health -= 1


#damage reduce by 1

func _on_stats_no_health():
		spawner(1)
		$Bat.play("death") #receives the no health signal and die
		yield($Bat, "animation_finished") #wait for animation to fully finish and queue free
		queue_free() 

func spawner(value):
	spawnvalue +=value #exponential growrth
	for i in range(0,spawnvalue): 
		emit_signal("spawn") #cals on bat spawn
func spawnenemy():
	var rand = RandomNumberGenerator.new()
	var enemyscn =load("res://Enemies/bat.tscn")
	var screen_size=get_viewport().get_visible_rect().size
	for i in range(0,40):
		var enemy = enemyscn.instance()
		rand.randomize()
		var x = rand.randf_range(0,screen_size.x)
		rand.randomize()
		var y = rand.randf_range(0,screen_size.y)
		add_child(enemy)

func _on_Timer_timeout():
	var Enemy = load ("res://Enemies/bat.tscn")
	var player =$Bat
	var e = Enemy.instance()
	var pos = player.position
	if randf() < 0.5: 
		# On the left
		pos.x -= rand_range(50.0, 200.0)
	else:
	# On the right
		pos.x += rand_range(50.0, 200.0)
	e.position = pos # the enemy position will be randomly either on left or right
	add_child(e) 	# add child to scene!
	

Rashid | 2020-07-18 18:28

the _on_stats_no_health() will be called by a signal when health <=0

If that signal is received by all bat-scenes, that would explain why killing one bat scene kills all the others as well. The code you provided does not show how you connect the signal, but why don’t you simply call _on_stats_no_health manually?

func _on_Hurtbox_body_shape_entered(body_id, body, body_shape, area_shape):
    stats.health -= 1
    _on_stats_no_health()

This would ensure it’s only called in the instance with zero health-points.

the spawner(1) is supposed to spawn another bat once it dies!

Though that will only happen the first time, because you’re increasing spawnvalue by the passed argument. So calling spawner(1) will emit the “spawn”-signal once, calling spanwer(1) once more will emit the “spawn”-signal twice and so on. Furthermore I assumme you connected the “spawn”-signal to spawnenemy, in which case you would spawn not just on but fourty (!) bats for each signal that is emitted!

On a sidenote: There’s no need to use RandomNumberGenerator here, you can use rand_range instead of RandomNumberGenerator.randf_range. Also you don’t need to call randomize() each time you generate a random number - doing it once (usually in _ready) is enough. In programming random numbers are an illusion and actually depend on what’s called a “seed” - if you know the seed and the algorithm, you can generate exactly the same sequence of “random” numbers over and over again. This is why you usually want to call randomize() to change the seed everytime your code is run. You can choose not to, but then the numbers will be the same each time.

Yes i connected it to the bat node

Then the line var player =$Bat is wrong! The bat-node in your image does not have any children at all, let alone one called “Bat”. Either way you should really migrate your code for spawning new enemies away from a specific instance. Otherwise the code cannot be run anymore once that instance is freed - as mentioned above.

njamster | 2020-07-18 20:12

thanks alot may you find success and luck wherever you are!

Rashid | 2020-07-18 21:54