Corona SDK: cancel timers with multiple instances of an object

In the last couple of days I have been stuck on killing the timer function within Corona SDK properly. I have searched on the web many solutions but somehow they did not work for me. I solved the issue, and I thought given the many entries already on the web I thought it would be useful to share my solution.

So when is this post useful for you? Probably when you try to solve one of the following:

- Error message: “Attempt to perform arithmetic on field ‘rotation’ (a nil value)”.
- timer.cancel does not work for you (and you don’t understand why :) ).
- When you created more instances of your display object (e.g. through a for-loop).

What is the problem (in which also the solution lies :) ) ? When you create multiple instances of an object (for example enemies or in my case it were propellors). A timer gets attached to each of the display objects, so you need to kill each of them separately. So when you create the timer you need to add them in a table (in my case proptimers = {} ), and loop through the table in a reverse manner to kill each of them.

So when you create your timer you need to store each timer instance in a table, so you can iterate later through the table.

I created a table called proptimers and I store each timer instance in the table
proptimers [#proptimers+1] = propellortimer (line 15)

Create a global variable:

proptimers = {}
for x = 0, 1 do 
-- you might just use display.newImage instead of display.newSprite
local prop = display.newSprite (myPlatformSheet, {frames={sheetInfo:getFrameIndex("propellor256")}}) 
	physics.addBody( prop, "static", physicsData:get("propellor256"))
	prop.x = centerX - centerX/2 * x 
	prop.y = centerY + centerY/2 * x 
	prop.myName = "propellor"
	group:insert(prop)
	
        local function rotateProp ()
			prop.rotation = prop.rotation + 20
	end
	
	propellortimer = timer.performWithDelay(100, rotateProp, -1)
	proptimers [#proptimers+1] = propellortimer
	print ("number of timers"..#proptimers)
	 
end 

Now you can kill the timers ( for example in a collision event) by using:

for i = #proptimers, 1, -1 do
     print ("number of timers stored"..#proptimers)
     timer.cancel (proptimers[i])
     proptimers[i] = nil
     print("killed "..i)
end

Somehow this bugged me for quite sometime, the solution created the typical “ah ha” response on my side, but given uite some discussion online as well on this topic, I thought it was useful to share this.

2 Responses

  1. Pulsy March 21, 2014 / 11:56 pm

    This works like a charm. I had trouble because some timers would end even after i killed my scene and switched to a new one, trying to execute functions on objects no longer in existance. This is all solved now :-)

  2. Bud July 28, 2014 / 12:58 pm

    This was the exact issue I was struggling with for a day or so.
    Lots of good vibes to you.
    thanks

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*