Multiple Collision events or multiple objects

Back to the balls rolling down ramps and hitting the bottom. I have colored balls zigzagging down some ramps to the bottom of the screen. When the balls hit the bottom I want them to reset to the top and roll down again. I can do this with a Runtime/enterFrame event listener watching the position of the balls as they fall. I am now trying to write the same program using a collision event listener. If I have one ball falling, no problem. The event listener watches the bottom object and waits for a collision on the bottom then resets the coordinates of the one ball to the top. The thing I cannot quite figure out is when I have two balls falling. If I have the event listener watching the ball then as soon as the ball hits any object it resets to the top. I want it to reset only when it hits the bottom. How do I get “when blue ball hits bottom reset to top or when red ball hits bottom reset to top”? Is there a method of having the collision detector detect what object the blue ball has hit and then execute depending on what the ball hit? At the moment I can only get the balls to reset simultaneously, not individually. [import]uid: 23256 topic_id: 23374 reply_id: 323374[/import]

You need to name things so you know what is colliding with what.

Eg for my challenge game:

[lua]sneakerAnim.name = “sneakers”
theStar.name=“star”[/lua]

then

[lua]local function onCollision( event )

local objName1, objName2 = event.object1.name, event.object2.name
if ( event.phase == “began” ) then
if (objName1 == “star” and objName2 == “sneakers”) or (objName1 == “sneakers” and objName2 == “star”) then
– etc[/lua] [import]uid: 10389 topic_id: 23374 reply_id: 93625[/import]

Great conversation! What if I needed to remove (destroy) the “star” object (in the situation above) at Collision? Since both objName1 and objName2 could the object “star” it is not possible to know in advance to say which objNameX will have the object “star” Would I simply do
[lua]if objName1 == “star” then

objName1:removeself()
objName1 = nil

elseif objName2 == “star” then

objName1:removeself()
objName1 = nil

end if[/lua]

Would that be the best way to delete a specific object when using multiple Collisions?

Thanks again for the thread!

Mo

ps: i am using a Runtime Collision Listener [import]uid: 49236 topic_id: 23374 reply_id: 93648[/import]

A little bit too sketchy for my knowledge level. The objects already have names when created. Do I have to give them a different type of name? The event.object1.name thing has me a bit confused. Heck, your line 3 format has me confused. I am OK with the event.phase idea. I will tinker excessively tomorrow and maybe it will make some sense but right now it is still pretty far out there. [import]uid: 23256 topic_id: 23374 reply_id: 93649[/import]

@gflint

I think what WauLok was referring to about naming your objects is that will help telling the Collision Listener what is what. For instance if you have two walls (top and bottom) and two balls (blue and red) You can deal with that by giving an extra name to those objects:
[lua]local topWall.name = top
local bottomWall.name =bottom
local blueBall.name = blue
local redBall.name = red

–then it is easy to make the balls go where you want them to --go. Like:

local function onCollision( event )

local objName1 = event.object1.name
local objName2 = event.object2.name

if ( event.phase == “began” ) then

if (objName1 == “blue” and objName2 == “bottom”) or (objName1 == “bottom” and objName2 == “blue”) then
– code here to reset blue ball to the top

elseif (objName1 == “red” and objName2 == “top”) or (objName1 == “top” and objName2 == “red”) then
– code here to reset red ball to the bottom

end[/lua]

" local objName1 = event.object1.name" line put the “name” of the first object who collide into a local variable objName1. Same for objName2. event.object1/2 are basically your object (ball or wall) By adding a new property “name”, you can help the system keep track of this things.

When two objects collide, you cannot know in advance how Corona would decide which one of your object is colliding with another (ie: which one is event.object1 orevent.object1) That is also why you need to check for both a ball colliding with a wall and vice-versa.
Hope this help.

Mo
[import]uid: 49236 topic_id: 23374 reply_id: 93651[/import]

Here is what I have so far using the above suggestions. It really does not appreciate line “bottomWall.name = “bottom””(and I assume the next two lines if it would get there). I am getting “attempt to index global ‘bottomWall’ (a nil value)”. I have tried putting “local bottomWall = “”” above it thinking I had to declare the variable first but no luck. I did figure out these have to be global or I get the error “unexpected symbol near ‘.’”.

[lua]require ( “physics” )
physics.start()
bottomWall.name = “bottom”
ballBlue.name = “ball_blue”
ballRed.name = “ball_red”
function buildObstacles()
ramp1 = display.newRect(0,200,300,10)
ramp1:setFillColor(255,0,0)
ramp1.rotation = 30
ramp2 = display.newRect(200,400,300,10)
ramp2:setFillColor(255,0,0)
ramp2.rotation = -30
ramp3 = display.newRect(0,600,300,10)
ramp3:setFillColor(255,0,0)
ramp3.rotation = 30
leftWall = display.newRect(0,0,10,850)
leftWall:setFillColor(255,0,0)
rightWall = display.newRect(470,0,10,850)
rightWall:setFillColor(255,0,0)
bottom = display.newRect(0,846,470,10)
bottom:setFillColor(255,255,0)
end
function InitializeBalls()
ball_blue = display.newImage( “ball_blue.png” )
ball_blue.x = 200
ball_blue.y = 0
physics.addBody( ball_blue, { bounce=0, radius = 15 } )

ball_red = display.newImage( “ball_red.png” )
ball_red.x = 200
ball_red.y = -40
physics.addBody( ball_red, { bounce=0, radius = 15 } )
end
buildObstacles()
InitializeBalls()
function hitBottom(event)
local objName1 = event.object1.name
local objName2 = event.object2.name

if ( event.phase == “began” ) then
if (objName1 == “ball_blue” and objName2 == “bottom”) or (objName1 == “bottom” and objName2 == “ball_blue”) then
ball_blue.y = 0
ball_blue.x = 100
ball_blue:setLinearVelocity(0,0)
elseif (objName1 == “ball_red” and objName2 == “bottom”) or (objName1 == “bottom” and objName2 == “ball_red”) then
ball_red.y = 0
ball_red.x = 100
ball_red:setLinearVelocity(0,0)
end
end
end

bottom:addEventListener( “collision”, hitBottom )
physics.addBody(bottom, “static”, {bounce = 0})
physics.addBody(rightWall, “static”)
physics.addBody(leftWall, “static”)
physics.addBody(ramp1, “static”, {bounce = 0})
physics.addBody(ramp2, “static”, {bounce = 0})
physics.addBody(ramp3, “static”, {bounce = 0})[/lua] [import]uid: 23256 topic_id: 23374 reply_id: 93779[/import]

Ignore that last post. I am an idiot. I figured out that problem (need to use the name of the object) but I still have other problems with the program. I will tinker some more. [import]uid: 23256 topic_id: 23374 reply_id: 93789[/import]

Boys and girls, we have success! It took me a couple of minutes to realize the event listener needed to be a Runtime. Here is the final code. I am still a little fuzzy about how the “event.object1.name” thing works. I am also a bit perplexed by the need for the timer. More reading required.

[lua]require ( “physics” )
physics.start()

function buildObstacles()
ramp1 = display.newRect(0,200,300,10)
ramp1:setFillColor(255,0,0)
ramp1.rotation = 30
ramp2 = display.newRect(200,400,300,10)
ramp2:setFillColor(255,0,0)
ramp2.rotation = -30
ramp3 = display.newRect(0,600,300,10)
ramp3:setFillColor(255,0,0)
ramp3.rotation = 30
leftWall = display.newRect(0,0,10,850)
leftWall:setFillColor(255,0,0)
rightWall = display.newRect(470,0,10,850)
rightWall:setFillColor(255,0,0)
bottom = display.newRect(0,846,470,10)
bottom:setFillColor(255,255,0)
end

function InitializeBalls()
ball_blue = display.newImage( “ball_blue.png” )
ball_blue.x = 200
ball_blue.y = 0
physics.addBody( ball_blue, { bounce=0, radius = 15 } )

ball_red = display.newImage( “ball_red.png” )
ball_red.x = 200
ball_red.y = -40
physics.addBody( ball_red, { bounce=0, radius = 15 } )
end

buildObstacles()
InitializeBalls()

bottom.name = “bottom”
ball_blue.name = “ball_blue”
ball_red.name = “ball_red”

function hitBottom(event)
timer.performWithDelay(1,function() return executeHitBottom(event) end )
end

function executeHitBottom(event)
local objName1 = event.object1.name
local objName2 = event.object2.name

if ( event.phase == “began” ) then
if (objName1 == “ball_blue” and objName2 == “bottom”) or (objName1 == “bottom” and objName2 == “ball_blue”) then
ball_blue.y = 0
ball_blue.x = 100
ball_blue:setLinearVelocity(0,0)
elseif (objName1 == “ball_red” and objName2 == “bottom”) or (objName1 == “bottom” and objName2 == “ball_red”) then
ball_red.y = 0
ball_red.x = 100
ball_red:setLinearVelocity(0,0)
end
end
end

Runtime:addEventListener( “collision”, hitBottom )

physics.addBody(bottom, “static”, {bounce = 0})
physics.addBody(rightWall, “static”)
physics.addBody(leftWall, “static”)
physics.addBody(ramp1, “static”, {bounce = 0})
physics.addBody(ramp2, “static”, {bounce = 0})
physics.addBody(ramp3, “static”, {bounce = 0})[/lua] [import]uid: 23256 topic_id: 23374 reply_id: 93797[/import]