Setting timer on an object

I have a question. I want to set a timer on an object so it disappears 3 seconds after it collides with another object. I know how to do the collision and destroy the objects on collision but I do not know how to set the timer to start once the collision is called. Heres an example:

[lua]function destroyBall(self)
display.remove(self);
end

function wall:collision(event)
if event.other.myName == “ball” then
timer.performWithDelay( 3000, destroyBall(event.other), 1 )
end
end[/lua]

How I am reading this is “When the wall and ball collide, destroyBall will be passed the ball and run after 3 seconds elapses.” But when I run this, the ball will disappear immediately. Can someone point me in the right direction as to what I am doing wrong? [import]uid: 50511 topic_id: 25028 reply_id: 325028[/import]

Try something like:

function collisionTest(event)  
 if event.phase == "began" then  
 if event.object1.myName == "wall" and event.object2.myName == "ball" then  
 timer.performWithDelay( 3000, delayTest, 1 )  
 function delayTest()  
 event.object2:removeSelf()  
 event.object2 = nil  
 end  
 end  
 end  
end  
Runtime:addEventListener( "collision", collisionTest )  

Im guessing you already have this set from your above code but just a reminder to give your wall.myName = “wall” [import]uid: 77199 topic_id: 25028 reply_id: 101712[/import]

Hmm, I am trying your snippet hatethinkingofnames, and seeing if I can implement it. The one problem that I have that I didn’t mention was, there are many ball objects. They are all created in a loop and therefore given the same name of “ball.” When I go to check collision I get errors an wonky things happen because there may be anywhere from 1 - 10 ball objects, yet only one is actually making a collision.

I think for some reason the code is being satisfied after the first ball makes the collision and then does not run again. I am still trying different ways to implement but could use any types of help! [import]uid: 50511 topic_id: 25028 reply_id: 101870[/import]

No problem, try this. It might have some lines of extra useless code but it works and you’ll understand how to do it. If you need more help feel free to ask

local spawnTrue = true;  
display.setStatusBar( display.HiddenStatusBar )  
local physics = require "physics"  
physics.start()  
physics.setDrawMode ( "normal" )  
--physics.setDrawMode ( "normal" )  
physics.setGravity( 0, 0 )  
  
local leftwall = display.newRect(0, 0, 1, display.contentHeight )  
local rightwall = display.newRect( display.contentWidth, 0, 1, display.contentHeight )  
local ceiling = display.newRect( 0, 0, display.contentWidth, 1 )  
ceiling.myName = "ceiling"  
  
physics.addBody(leftwall, "static", { bounce = 0.1 } )  
physics.addBody(rightwall, "static", { bounce = 0.1 } )  
physics.addBody(ceiling, "static", { bounce = 0.1 } )  
local ground = display.newRect( 0, 0, 320, 50)  
ground:setReferencePoint( display.BottomLeftReferencePoint )  
ground.x, ground.y = 0, 540  
  
local groundShape = { -240,-20, 240,-20, 240,20, -240,20 }  
physics.addBody( ground, "static", { friction=1.0, density=1.0, bounce=0 } )  
  
balloon = {}  
local i = 1  
local randomPos = math.random ( 0, 320 )  
  
local function moveShit(event)   
 local fattie = event.target  
 fattie:applyLinearImpulse( 0, -5, event.x, event.y )  
end  
  
local function spawnStuff( event )  
  
 if spawnTrue == true then  
 balloon[i] = display.newCircle( math.random( 0, 320), 320, 15 )  
 balloon[i]:setFillColor( 0, 0, 255 )  
 balloon[i].x = math.random( 0, 320 )  
 balloon[i].y = 230  
 balloon[i].myName = "balloon"  
 physics.addBody(balloon[i] , "dynamic", { radius = 17 })  
 balloon[i]:addEventListener( "touch", moveShit )  
 i = i + 1  
 end  
 end  
  
spawnBalls = timer.performWithDelay( 1500, spawnStuff, 0 )  
local function moveShit(event)   
 local fattie = event.target  
 fattie:applyLinearImpulse( 0, -5, event.x, event.y )  
end  
  
local testNum = 0;  
  
local function onCollideObject(event)  
 if ( event.phase == "began" ) then  
 if event.object1.myName == "ceiling" and event.object2.myName == "balloon" then  
  
 timer.performWithDelay( 3000, delayTest, 1 )  
 function delayTest()  
 event.object2:removeSelf()  
 event.object2 = nil  
 end  
  
  
  
  
 end   
 end  
end  
   
Runtime:addEventListener( "collision", onCollideObject)  

The parts you are most interested is in spawnStuff and then you already saw the collide code. Click on the balls to make them hit the wall btw

EDIT: Meh its currently off by one, Ill try to fix it later gotta go now [import]uid: 77199 topic_id: 25028 reply_id: 101883[/import]

I am also getting the same issue. For some reason it is only activating the first balloon’s timer after the second balloon hits the wall. After re-evaluating, I can see that I will not need more then 4 “balloons” at a time so I may remove the loop and add four functions. I know this is bad practice and I will probably be tarred and feathered by other programmers, but I think if I can get it to work I will understand the method better. Then I could go back and try and re implement the loop.

With 4 functions (spawnStuff1,…, spawnStuff4) I could set the names of the balloons in each. Therefore checking for “balloon1”, “balloon2”, etc… [import]uid: 50511 topic_id: 25028 reply_id: 101893[/import]

How exactly do you want your balls to spawn? All at once or randomly seperate or? [import]uid: 77199 topic_id: 25028 reply_id: 101906[/import]

I have them spawning when you click a certain object. So when you click this object (pos1) it calls this function (throwBall()):

[lua]local bags = {}
local n = 0
local bagsYpos = 0;

local function throwBall()
–n = n + 1
if (lives > 0) then
ballYpos = pos1.y;

ball[n] = display.newImage( “images/ball1.png”, -20, ballYpos - 20)
physics.addBody( ball[n], { density=6.0, friction=0.5, bounce=0.00 } )
ball[n].myName = “ball”

GUI:insert(ball[n]);

ball[n].angularVelocity = 100
ball[n]:applyForce( 5050, 0, ball[n].x, ball[n].y )
lives = lives - 1;
livesNum.text = lives;
ball[n]:addEventListener(“collision”, ball)
else
gameOverText.isVisible = true
end

end

local function destroyBall(self, event)
display.remove(self)
end

function ball:collision (self, event)
if event.other.myName == “wall” then
timer.performWithDelay( 3000, destroyBall(self) )
end
end [/lua]

Assume that all variables such as lives and gameOvertext are all properly initialized. Pos1 has a listener on it that listens for a “touch” on itself. When you touch Pos1, this function is called to spawn a ball at Pos1’s y position and send it flying in the X direction towards the wall. Once it hits the wall, I would like it to disappear after 3 seconds. Almost like a countdown I guess.

An issue I possibly run into is that you can click Pos1 multiple times and depending on the “lives” variable, it will either fire a ball, or tell the user its game over. but if you fire a ball before the previous ball hits the wall this will create an issue, I’m assuming. [import]uid: 50511 topic_id: 25028 reply_id: 101913[/import]

Yeah if you make 4 balls seperately and give them myNames = “ball1” “ball2” etc it should work fine. I dont think its bad code if you dont loop it, especially since its only 4 balls. This way you have exact control over all of them. Im at work now so cant really help you but if you need help leave a post and ill get to it tonight. Either way let me know if you managed to do it, good luck [import]uid: 77199 topic_id: 25028 reply_id: 101937[/import]

@roymanfredi

I didn’t read every post, I mostly just looked at your first post. The timer code you are using is indeed firing immediately. Elsewhere on the forums it’s explained why, I don’t remember the technicals of it. However this is how you get around it.

You can only pass a listener to the timer. If you need to pass parameters to the listener, wrap it in a function like so.

timer.performWithDelay( 3000, function() destroyBall(self) end)  

That should work. [import]uid: 56820 topic_id: 25028 reply_id: 101957[/import]

@hatethinkingofnames I created separate functions for each time a ball is spawned. Therefore giving each ball a unique name (ball1, ball2, etc.). That pretty much fixed everything! The only thing to make sure of is changing the wall’s collision if statement to say ball1 or ball2 or ball3 instead of just ball.

@anderoth Okay adding a function in there works like a charm! this will make it much easier to pass objects into the timer’s code and attach timers to different objects. Thanks! [import]uid: 50511 topic_id: 25028 reply_id: 102152[/import]