0 votes

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:https://imgur.com/gallery/rUxR2s9

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!
in Engine by (37 points)
edited by

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?

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()

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?

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!

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.

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

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.