0 votes

Hello everyone.

Currently, I've been trying to make a functional script to spawn enemies (which is a falling meteor in my game).

Here's my current script:

extends Node

const meteors = [
   preload("res://scenes/meteor.tscn")
]

func _ready():
   yield(utils.create_timer(1.2), "timeout")
   spawn()
   pass

func spawn():
   while true:
       randomize()
       var m = utils.choose(meteors).instance()
       var p = Vector2()
       p.x   = rand_range(0+16, utils.view_size.x-16)
       p.y   = 0-16
       m.position = p
       $container.add_child(m)
       yield(utils.create_timer(rand_range(0.5, 1.25)), "timeout")
   pass

And so far it works, here's how it looks: (screenshot link below...)
http://prntscr.com/snvmi7

But my question is how to stop the spawner at the specific time? and then activate another spawner afterwards?

My idea for this is for example:

After the player managed to survive the falling meteor shower for 30 seconds, the spawner of this type of meteor (which I regard as the first spawner) would stop spawning meteors. Then the next spawner (that features a new and faster meteor sprite, which I regard as the second spawner) would start active.

I had found various tutorials online (like in youtube) on how to make a spawner in godot. But so far, none of them had ever described how to stop it at a specific time.

Is this had to do with how the timer works? I'm curious to know. If someone could write a specific explanation in detail, that would be appreciated.

~ Regards

in Engine by (22 points)

1 Answer

0 votes
Best answer

Here you go:

extends Node

const meteors = [
    preload("res://scenes/meteor.tscn")
]

var meteor_shower = false

func _ready():
    yield(utils.create_timer(1.2), "timeout")
    spawn()
    yield(utils.create_timer(30.0), "timeout")
    meteor_shower = false

func spawn():
    meteor_shower = true
    while meteor_shower:
        randomize()
        var m = utils.choose(meteors).instance()
        var p = Vector2()
        p.x   = rand_range(0+16, utils.view_size.x-16)
        p.y   = 0-16
        m.position = p
       $container.add_child(m)
       yield(utils.create_timer(rand_range(0.5, 1.25)), "timeout")

I only introduced a new variable, a boolean called meteor_shower defaulting to false. When spawn() is called, it's set to true before the while-loop starts, that will run for as long as meteor_shower is true. So far that will behave exactly the same as your code. However, after calling spawn() in _ready() I call another timer (of 30 seconds) after which meteor_shower is reset to false - y voilla, the while-loop will stop!


For future questions I recommend that you provide your utils-script as well, if you're using it. I remembered your last post, but you cannot expect everyone to do so. Also I allowed myself to remove the pass-keywords from both _ready() and spawn() - they don't do anything. Use them where GDscript expects a line of code and you're not ready to add this line, e.g. after a function-definition or an if- or else-case.

by (10,281 points)
selected by
  • Great, it stops the spawner in exactly 30 seconds (I've decided of making it longer up to 1 minute). Now how to make the second spawner active after the first spawner had stopped?

  • Understandable, I shall follow your recommendations on future questions.

  • Regarding the pass keyword, I always thought that we need to add that keyword at every end of each function (Currently, each function in my code always had that keyword in the end). Thanks for your info.

Now how to make the second spawner active after the first spawner had stopped?

The logic is always the same: you wait a certain amount of time, then you spawn the meteor shower, wait more and then deactivate it again by setting meteor_shower to false. Here's an endless loop of spawning meteors in random intervals:

func _ready():
    randomize()

    while true:
        var wait_time = rand_range(1.0, 5.0)
        yield(utils.create_timer(wait_time), "timeout")
        spawn()
        wait_time = rand_range(10.0, 30.0)
        yield(utils.create_timer(wait_time), "timeout")
        meteor_shower = false
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.