I’m trying to wait until a condition is met, in this case until all enemies have been defeated in a wave. This is my code:
while self.enemies_alive > 0 do
-- rest of code goes here
end
I’ve used while loops before, more so in Luau (an altered version of Lua). That version requires you to use “wait()” to ensure the script doesn’t time out.
However, when i run this code, my game crashes. I can’t find anything else on the forum or on the internet regarding while loops in defold, so is it a real thing?
If it is, how do i ensure it doesn’t crash my game?
A while loop like in your example will run until that condition is met, but it will not execute any other code than what you have inside the loop. This means that you will block the entire game engine from running any code. This is why the game crashes/hangs.
You need to restructure your code and check for this condition once per frame. You can perhaps use the life cycle functions to achieve this?
function init(self)
-- add your game init code here
end
function update(self, dt)
if self.enemies_alive > 0 then
-- run code while enemies are alive here
end
end
The question is how you decrease self.enemies_alive? Perhaps at the place where you decrease this value you can also check if you the new value is zero and then call some code to stop the game and run the code you wanted to put after your while-loop.
A kind of compromise I find myself using when the suggestions by britzl aren’t appropriate is to use a timer to check the condition periodically! It might be overkill to check every frame and more reasonable to check every second. (Of course the opposite is true too - it might be absolutely fine to check every frame!)
function spawn_wave(self)
while self.current_wave < self.max_waves do
for i = 1,self.enemies_perwave do
msg.post("#enemy", "spawn_enemy")
self.total_enemies = self.total_enemies + 1
end
print(self.total_enemies,"is the total number of enemies")
-- do some sort of loop that runs while enemies > 0
timer.delay(1, true, function()
if self.total_enemies == 0 then
timer.cancel(handle))
end
end)
print("the wave has been defeated")
end
end
function on_message(self, message_id, message, sender)
if message_id == hash("enemy_dead") then
self.total_enemies = self.total_enemies - 1
end
end
And the game still crashes. Should I still replace the main while loop with some sort of ‘timer’ utilization?
You should not use ‘while’ and ‘timer’ together. Get rid of the while loop and just use the timer.
In your last code snippet the timer does nothing but checking if total enemies is zero.
The timer in your code does indeed wait but you are not using it correctly.
waitthing = timer.delay(1, true, function()
-- here goes the code you want to run on every tick,
-- basically the while loop above but without the while :)
if self.total_enemies == 0 then
timer.cancel(waitthing)
end
end)
function spawn_wave(self) -- issue with this: it creates all the waves and doesnt wait until the wave is complete
waitthing = timer.delay(1, true, function()
for i = 1,self.enemies_perwave do -- make it so the maximum number of total_enemies is 5
msg.post("#enemy", "spawn_enemy")
self.total_enemies = self.total_enemies + 1
end
self.current_wave = self.current_wave + 1
print(self.total_enemies,"is the total number of enemies")
-- do some sort of loop that runs while enemies > 0
if self.total_enemies == 0 then
timer.cancel(waitthing)
end
end)
end
Now my problem is that it doesn’t wait for the wave to be over before looping again.
How would I implement this? Do I need to put an ‘else’ and force it to wait?