I mean that it chooses the same number every time as the delay.
Show us your exact timer code… (cut-copy-paste it into a code box)
function spawnEnemies() temp = math.random(1, 4) if temp == 1 then enemy = display.newSprite(beetle, beetleSequenceData) enemy.x = \_R + 100 enemy.y = \_CY enemy.hasBeenScored = false physics.addBody(enemy, "dynamic", physicsData:get("beetle")) enemy.xScale = -1 enemy.id = "enemy" enemy.isFixedRotation = true enemy:play() group:insert(enemy) elseif temp == 2 then enemy2 = display.newSprite(vulture, vultureSequenceData) enemy2.x = \_R + 100 enemy2.y = \_CY - (enemy2.height \* 0.25) enemy2.hasBeenScored = false physics.addBody(enemy2, "dynamic", physicsData:get("vulture")) enemy2.xScale = -1 enemy2.gravityScale = -0.01 enemy2.id = "enemy2" enemy2.isFixedRotation = true enemy2:play() specialGroup:insert(enemy2) elseif temp == 3 then enemy3 = display.newSprite(scorpion, scorpionSequenceData) enemy3.x = \_R + 100 enemy3.y = \_CY enemy3.hasBeenScored = false physics.addBody(enemy3, "dynamic", physicsData:get("scorpion")) enemy3.xScale = -1 enemy3.id = "enemy3" enemy3.isFixedRotation = true enemy3:play() group:insert(enemy3) else enemy4 = display.newSprite(bee, beeSequenceData) enemy4.x = \_R + 100 enemy4.y = \_CY - (enemy4.height \* 0.25) enemy4.hasBeenScored = false physics.addBody(enemy4, "dynamic", physicsData:get("bee")) enemy4.xScale = -1 enemy4.gravityScale = -0.01 enemy4.id = "enemy4" enemy4.isFixedRotation = true enemy4:play() specialGroup:insert(enemy4) end timer.performWithDelay(math.random(2000, 4000), spawnEnemies) end
elseif ( phase == "did" ) then -- Code here runs when the scene is entirely on screen print("shown") physics.start() timer.performWithDelay(math.random(2000, 4000), spawnEnemies) moveEnemiesTimer = timer.performWithDelay(2, moveEnemies, -1) end
Edit: Only one enemy spawns.
This is all the code relating to the timer.
Also, when I am done with this can I just cancel all timers with timer.cancel()? If I can’t do this then how?
If you call timer.cancel with no arguments then you cancel all active timers (unless they have their exclude parameter set to true)
Read more http://www.jasonschroeder.com/2015/02/25/timer-2-0-library-for-corona-sdk/
-
It is bad practice to make that function global.
-
That code should work just fine.
Make yourself a basic test case exercising just this concept and prove it to yourself, then apply it to your app.
Here is a test case:local iterations = 0 local function doit() print("Entered doit() at ", system.getTimer() ) iterations = iterations + 1 if( iterations > 5 ) then return end timer.performWithDelay( math.random(2000, 4000), doit ) end timer.performWithDelay( math.random(2000, 4000), doit )
I get this in the console when I run the above code:
12:55:29.948 Entered doit() at 4014.9 12:55:32.975 Entered doit() at 7046.8 12:55:35.584 Entered doit() at 9659.6 12:55:37.627 Entered doit() at 11702.2 12:55:39.823 Entered doit() at 13890.1
I also found using timer.cancel() without any parameters is not working for me, it crashes my app.
Yeah, that would be a bad idea as it will cancel ALL timers, some of which you might need.
Note: You should really keep it ONE TOPIC PER POST. You started this post about randomizing timers, you should open a separate post about cancelling timers.
I don’t mean to sound like a jerk, but this is bad forum etiquette, and more importantly, you dilute the value of the thread to future readers. I answer posts to help the current person and future people.
I apologize for this, I was not aware of bad “forum” manners.
No need to apologize, just pointing it out so you know. I’m keen on helping folks, and threads that morph are one of my pet peeves (behind hijackings which really get my goat)… speaking of which, back on topic.
Again, try my standalone example and you’ll see the concept is sound. Then apply it to your app and you should be golden.
They are spawning at random now, I had made a silly mistake before, but they only spawn 6 enemies and the timer stops.
Well, it isn’t stopping because the timer is failing. It is stopping because somewhere in your code you are not calling the timer.performWithDelay() function.
Add print statements at each point where that function can exit and see if it exits without executing timer.performWithDelay().
The easiest way to do this if your function has NO return statements is to do something like this:
function spawnEnemies() print("Entered spawnEnemies @ ", system.getTimer() ) -- first line ... print("Calling spawnEnemies @ ", system.getTimer() ) -- Right before every call to performWithDelay timer.performWithDelay(math.random(2000, 4000), spawnEnemies) ... print("Exitting spawnEnemies @ ", system.getTimer() ) -- last line end
I’m sorry but what do you mean by the function can exit?
-
I added comments to my answer above, so go back and check them out.
-
If you follow those instructions, you’ll see messages like this:
13:11:43.352 Entered spawnEnemies @ 2605.4 13:11:43.352 Calling spawnEnemies @ 2605.4 13:11:43.352 Exited spawnEnemies @ 2605.4 … 13:11:52.776 Entered spawnEnemies @ 12029 13:11:52.776 Calling spawnEnemies @ 12029 13:11:52.776 Exited spawnEnemies @ 12029
-
If you see messages like this:
13:11:43.352 Entered spawnEnemies @ 2605.4 13:11:43.352 Calling spawnEnemies @ 2605.4 13:11:43.352 Exited spawnEnemies @ 2605.4 … 13:11:52.776 Entered spawnEnemies @ 12029 13:11:52.776 Exited spawnEnemies @ 12029
,then you are skipping the call to performWithDelay() in your code
PS - I’ve gotta get back to work, so I won’t be answering any more for now. Anyways, I think you’re armed with the info you need now.
PPS - By ‘can’ exit, I meant any place where the function can be exited. Typically this is only at the end of the function, but if you have a return statement earlier in an if-statement or elsewhere in the function then, that is an alternate exit point.
function spawnEnemies() print("Entered spawnEnemies @ ", system.getTimer() ) -- first line temp = math.random(1, 4) if temp == 1 then enemy = display.newSprite(beetle, beetleSequenceData) enemy.x = \_R + 100 enemy.y = \_CY enemy.hasBeenScored = false physics.addBody(enemy, "dynamic", physicsData:get("beetle")) enemy.xScale = -1 enemy.id = "enemy" enemy.isFixedRotation = true enemy:play() group:insert(enemy) elseif temp == 2 then enemy2 = display.newSprite(vulture, vultureSequenceData) enemy2.x = \_R + 100 enemy2.y = \_CY - (enemy2.height \* 0.25) enemy2.hasBeenScored = false physics.addBody(enemy2, "dynamic", physicsData:get("vulture")) enemy2.xScale = -1 enemy2.gravityScale = -0.01 enemy2.id = "enemy2" enemy2.isFixedRotation = true enemy2:play() specialGroup:insert(enemy2) elseif temp == 3 then enemy3 = display.newSprite(scorpion, scorpionSequenceData) enemy3.x = \_R + 100 enemy3.y = \_CY enemy3.hasBeenScored = false physics.addBody(enemy3, "dynamic", physicsData:get("scorpion")) enemy3.xScale = -1 enemy3.id = "enemy3" enemy3.isFixedRotation = true enemy3:play() group:insert(enemy3) else enemy4 = display.newSprite(bee, beeSequenceData) enemy4.x = \_R + 100 enemy4.y = \_CY - (enemy4.height \* 0.25) enemy4.hasBeenScored = false physics.addBody(enemy4, "dynamic", physicsData:get("bee")) enemy4.xScale = -1 enemy4.gravityScale = -0.01 enemy4.id = "enemy4" enemy4.isFixedRotation = true enemy4:play() specialGroup:insert(enemy4) end print("Entered doit() at ", system.getTimer() ) iterations = iterations + 1 if( iterations \> 5 ) then return end print("Calling spawnEnemies @ ", system.getTimer() ) timer.performWithDelay( math.random(2000, 4000), spawnEnemies ) print("Exitting spawnEnemies @ ", system.getTimer() ) end --Under scene:show phase == "did" print("Calling spawnEnemies @ ", system.getTimer() ) timer.performWithDelay(math.random(2000, 4000), spawnEnemies)
This is your problem.
if( iterations > 5 ) then return end
This is a point where it can (and will) exit the function.
No worries, thank you for all your help, when you are free:
It had exited without execution on the iterations return statement. So should I get rid of it?
Sincerely,
Alex
I got it working it is randomized and does not stop.