assigning a timer for each instance of object created

Hello everyone,

I have an issue with timers. I’m using timermanager and transitionmanager from Alfred R. Baudisch <alfred.r.baudisch@gmail.com>.

I have a timer to spawn an enemy ship every 2000ms using function spawnEnemy(). Which works well, but I need each ship to fire a bullet every 500ms using function shoot().

The following code below spawns the ships but only fires the bullet ones per each ship. It seems as the timer object gets reassigned. I’ve searched through the web for a while and couldn’t find a solution, maybe someone has a fix to my problem?

local composer = require( "composer" ) local transM = require("manager.transitionManager") local timers = require("manager.timerManager") transM = transM.new() local spawnBullet local removeEnemy local spawnEnemy local enemy local contentH = display.contentHeight local contentW = display.contentWidth local tmBullet --Create a table to hold our spawns local spawnTable = {} local bulletTable = {} local localGroup = display.newGroup() -- physics local physics = require("physics") physics.start() physics.setGravity( 0,0) --Function to spawn an object local function spawn(params) &nbsp;&nbsp; &nbsp;local object = display.newImage(params.image) &nbsp;&nbsp; &nbsp;object.x = params.x &nbsp;&nbsp; &nbsp;object.y = params.y &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;--Set the objects table to a table passed in by parameters &nbsp;&nbsp; &nbsp;object.objTable = params.objTable &nbsp;&nbsp; &nbsp;--Automatically set the table index to be inserted into the next available table index &nbsp;&nbsp; &nbsp;object.index = #object.objTable + 1 &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;object.tr = transM:add(object, { y=params.transY, time=params.transT }) &nbsp;&nbsp; &nbsp;print (object.tr) &nbsp;&nbsp; &nbsp;--Give the object a custom name &nbsp;&nbsp; &nbsp;object.myName = "Object : " .. object.index &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;--If the object should have a body create it, else dont. &nbsp;&nbsp; &nbsp;if params.hasBody then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;--Allow physics parameters to be passed by parameters: &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;object.density = params.density or 0 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;object.friction = params.friction or 0 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;object.bounce = params.bounce or 0 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;object.isSensor = params.isSensor or false &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;object.bodyType = params.bodyType or "dynamic" &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;physics.addBody(object, object.bodyType, {density = object.density, friction = object.friction, bounce = object.bounce, isSensor = object.isSensor}) &nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;print ("added body") &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;--The objects group &nbsp;&nbsp; &nbsp;object.group = params.group or nil &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;--If the function call has a parameter named group then insert it into the specified group &nbsp;&nbsp; &nbsp;object.group:insert(object) &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;--Insert the object into the table at the specified index &nbsp;&nbsp; &nbsp;object.objTable[object.index] = object &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;return object end function spawnEnemy() &nbsp;&nbsp; &nbsp;local spawns = spawn( &nbsp;&nbsp; &nbsp;{ &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;image = "images/plane.png", &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;objTable = spawnTable, &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;x = math.random ( 25, contentW - 25 ), &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;y = -100, &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;group = localGroup, &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;transY = contentH, &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;transT = 6500, &nbsp;&nbsp; &nbsp;}) &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;timers:add(500, shoot(spawns.index), 0) &nbsp;&nbsp; &nbsp; end function shoot( idx ) &nbsp;&nbsp; &nbsp;print("#" .. #spawnTable) &nbsp;&nbsp; &nbsp;local bulletSpawns = spawn( &nbsp;&nbsp; &nbsp;{ &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;image = "images/bullet.png", &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;objTable = bulletTable, &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;group = localGroup, &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;x = spawnTable[idx].x, &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;y = spawnTable[idx].y, &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;density = 1, &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;bodyType = "static", &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;transY = contentH, &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;transT = 1000 &nbsp;&nbsp; &nbsp;}) &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;print("timer=" .. #bulletTable) end local function ignoreTouch( event ) &nbsp;&nbsp; &nbsp;return true end local t1 = timers:add( 2000, spawnEnemy, 0 )

Thanks!

Without knowing more about that timer library, it sounds like the timer is getting overwritten for each enemy that is being created. You might be better off forgoing the timer library for that particular use, as it’s just as easy to create a table variable as the timer assignment.

local varTimer = {} local function cancelvarTimers() -- I like having a function that cancels all the timers in the table, for when I need to restart or otherwise pull the ripcord. local k, v for k,v in pairs(varTimer) do timer.cancel( v ) v = nil; k = nil end varTimer = nil varTimer = {} --varTimer[#varTimer+1] = -- this is the code needed to create another timer. return cancelvarTimers end -- new spawn code: function spawnEnemy() local spawns = spawn( { image = "images/plane.png", objTable = spawnTable, x = math.random ( 25, contentW - 25 ), y = -100, group = localGroup, transY = contentH, transT = 6500, }) varTimer[#varTimer+1] = timer.performWithDelay(500, shoot(spawns.index), 0) end

Or you could figure out how to implement the above within your timer library. I assume it would be possible, as it wouldn’t be much of a help if it left out this ability. From the syntax you’ve provided, it looks like they are creating metatables and classes so it should be in there.

HTH

I solved the timer issue by specifying function within the timer call like so,

myApp.spawns.tr = timers:add(500, function() &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;shoot(spawns.index) end, 0)

I had a feeling that creating a timer as such,

myApp.spawns.tr = timers:add(500, shoot(spawns.index), 0)

Overwritten the previous timer for this function, the index supplied is dynamic.

I’m not sure exactly why this fixed the issue, I can only guess without going low level.

Without knowing more about that timer library, it sounds like the timer is getting overwritten for each enemy that is being created. You might be better off forgoing the timer library for that particular use, as it’s just as easy to create a table variable as the timer assignment.

local varTimer = {} local function cancelvarTimers() -- I like having a function that cancels all the timers in the table, for when I need to restart or otherwise pull the ripcord. local k, v for k,v in pairs(varTimer) do timer.cancel( v ) v = nil; k = nil end varTimer = nil varTimer = {} --varTimer[#varTimer+1] = -- this is the code needed to create another timer. return cancelvarTimers end -- new spawn code: function spawnEnemy() local spawns = spawn( { image = "images/plane.png", objTable = spawnTable, x = math.random ( 25, contentW - 25 ), y = -100, group = localGroup, transY = contentH, transT = 6500, }) varTimer[#varTimer+1] = timer.performWithDelay(500, shoot(spawns.index), 0) end

Or you could figure out how to implement the above within your timer library. I assume it would be possible, as it wouldn’t be much of a help if it left out this ability. From the syntax you’ve provided, it looks like they are creating metatables and classes so it should be in there.

HTH

I solved the timer issue by specifying function within the timer call like so,

myApp.spawns.tr = timers:add(500, function() &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;shoot(spawns.index) end, 0)

I had a feeling that creating a timer as such,

myApp.spawns.tr = timers:add(500, shoot(spawns.index), 0)

Overwritten the previous timer for this function, the index supplied is dynamic.

I’m not sure exactly why this fixed the issue, I can only guess without going low level.