How can I have a random delay occur for every time the timer is run?
local function doit() -- do something here timer.performWithDelay( math.random( 1000, 2000 ), doit ) end timer.performWithDelay( math.random( 1000, 2000 ), doit )
Read about math.random and math.randomseed Know more http://lua-users.org/wiki/MathLibraryTutorial
Hope this help 
When I try using timer.performWithDelay( math.random( 2000, 4000 ), etc, -1 )
It always end up choosing the same number every time. It is not random at all.
That isn’t how it works…
This code:
timer.performWithDelay( math.random( 2000, 4000 ), function() end , -1 )
Literally does this:
- Evaluates ‘math.random(2000,4000)’ and passes that value as argument ONE to timer.performWithDelay()
- For this example, let’s assume the return value of ‘math.random(2000,4000)’ is 1500
-
Creates ‘function() end’ and passes a reference to the new closure as argument TWO to timer.performWithDelay(
-
Passes -1 as argument THREE to timer.performWithDelay() which says ‘loop forever’.
Now, the timer executes every ~1500 ms and calls the function that was passed in argument TWO.
If you want to get a new random time value every time you need to call it the way I showed you above… i.e. Do not call it with -1 arg and re-call it at the end of the function that you do work in.
It is still not random, this is my code:
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
Also, how can I remove all timers?
Thank you for your help.
I believe timer.cancel() will cancel all timers, but you should store your timers into a variable. Something like tmr_createEnemies = timer.performWithDelay(1000, spawnEnemies, 1). Then, you can cancel the timer by doing timer.cancel(tmr_createEnemies).
Ok, but I am still having problem with setting a random delay to a timer.
What? and what do you mean it is not random?
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.