Collision on Static Display Object...

What I’d like to do is have “zones” on the screen and when objects enter the zone something happens. I tried making the zones static objects with isSensor set to true, but that didn’t seem to work because I could never get an event to fire for the static object (zone). The game I’m working on is simple and all I really need to be able to do is know when an object is within the bounds of another object and when it exits. I know that bounds checking is pretty easy to do mathematically, but what event/listener combination do I use to check bounds? Is that even the right approach? Is there another feature of Corona that I’m missing. Seems like this is “Games 101” stuff, but as a noob I’m not seeing how to accomplish this simple task.

So I guess my question in a nutshell is: how would one implement a rolling marble that triggers certain events when it rolls in and out of predefined zones on the screen? [import]uid: 9977 topic_id: 10626 reply_id: 310626[/import]

I did something similar and this is what I used:

physics.addBody( capital, "static", { density=1.6, friction=1.0, bounce=0.0, radius=24, isSensor = true } )  

Then you need an event handler for the collision:

function onMyCollision( self, event )  
 print("collision detected between " .. self.myName .. " and " .. event.other.myName)  
 if ( event.phase == "began" ) then  
 print( self.myName .. ": collision began with " .. event.other.myName )  
 end  
end  

Then for my attacking object:

 me = display.newImage("me.png");  
 me.x = display.contentWidth - 15;  
 me.y = math.random((display.contentHeight - 70)) + 30;  
 physics.addBody( me, "dynamic", { density=0.0, friction=1.0, bounce=0.0, isBullet = true } )  
 me:addEventListener( "touch", onMyTouch )  

Maybe you will spot something in there that you’re missing.

Rob [import]uid: 19626 topic_id: 10626 reply_id: 38616[/import]

Hey thanks for the response Rob. I’ve tried something similar, but it didn’t work because the static object never fired the event for onCollision to receive. I can get my dynamic objects to collide and fire events no problem, but they just pass through my static objects without firing any collision event (that I know of).

I notice that you aren’t adding onMyCollision as a local listener. Does this work? Does your onMyCollision automatically fire on collision events?

I think I’m more concerned with “is one object overlapping another object?” more than “are two objects colliding?”. I need to figure out how to make this determination, for a couple dozen dynamic objects, within the game loop. Should be easy, and I’m sure it is, but I’m kind of stumped.

[import]uid: 9977 topic_id: 10626 reply_id: 38617[/import]

I’d like to add that determining overlap isn’t the issue. That part is easy. Where I’m stumped is when and how to call the code that does the bounds checking. As my dynamic object moves across the screen how do I call a function to test that it is overlapping one of my static zones? Is there some kind of global/runtime tick or frame event that is fired?

I think the pool pockets on the pool demo do exactly what I’m trying to do so I’m reviewing that code now. I’m sure I’m just overlooking something that is common knowledge for people with more Corona experience. [import]uid: 9977 topic_id: 10626 reply_id: 38618[/import]

Here is how it is done in the pool demo. I’ll try something like this (again), but I’m still not sure this is the right way to solve this specific problem. For example if my dynamic object is overlapping three different zones and I want all three to be lit up while the dynamic object passes over them won’t handling the events be a code nightmare when a simple bounds check would do the trick?

[code]
–Sets up pockets
function inPocket( self, event )

local fallDown = transition.to( event.other, { alpha=0, xScale=0.3, yScale=0.3, time=200 } )
local object = event.other

event.other:setLinearVelocity( 0, 0 )

if event.other.type == “cueBall” then
timer.performWithDelay( 50, resetCueball )

elseif event.other.type == “solid” and event.other.active == true then
event.other.active = false
–Update Solid Score
solidTotal = solidTotal + 1
solidScoreText.text = solidTotal
elseif event.other.type == “stripe” and event.other.active == true and mode == 2 then
event.other.active = false – Prevents balls from
–Update Stripe Score
stripeTotal = stripeTotal + 1
stripeScoreText.text = stripeTotal
elseif event.other.type == “eightBall” then
gameOver()
end

end

– Create pockets
function setPockets()
local pocket = {}
for i = 1, 3 do
for j = 1, 2 do
local index = j + ((i-1) * 2) – a counter from 1 to 6

– Add objects to use as collision sensors in the pockets
local sensorRadius = 20
pocket[index] = display.newCircle( -389 + (515*j), -436 + (474*i), sensorRadius )
stageGroup:insert(pocket[index])

– (Change this value to “true” to make the pocket sensors visible)
pocket[index].isVisible = false
physics.addBody( pocket[index], { radius=sensorRadius, isSensor=true } )
pocket[index].id = “pocket”
pocket[index].bullet = false
pocket[index].collision = inPocket
pocket[index]:addEventListener( “collision”, pocket[index] ) – add table listener to each pocket sensor

end
end
end
[/code] [import]uid: 9977 topic_id: 10626 reply_id: 38621[/import]

I only have the listener on the thing that is moving. When it hits anything, another dynamic object or a static object, I get an event fired on my dynamic object. The static objects themselves don’t need to process events when the dyanmic ones are.

I can see the logic where you are wanting to say “did something overlap me” but its the same thing to say from the dyanmic object that is doing the moving “did I overlap something” and then “what did I overlap”. Its this last model that I’m doing.

In other words static objects can only be hit by dynamic objects. So you don’t need both objects generating events and to me it makes more sense to have that event is more logical to be passed to the dynamic object.

[import]uid: 19626 topic_id: 10626 reply_id: 38622[/import]

You could assign each static object an id such as:

staticObject1.id = "object1"  
staticObject2.id = "object2"  

Then within the collision event check the id of the static object like:

local function staticCollision(self,event)  
 if event.phase == "began" then  
 print("collision began")  
 if event.other.id == "object1"  
 print("collision with object1")  
 elseif event.other.id == "object2"  
 print("collision with object2")  
 end  
 elseif event.phase == "ended" then  
 print("collision ended")  
 end  
end  

[import]uid: 27965 topic_id: 10626 reply_id: 38623[/import]

Thanks everyone for the help. I was able to implement something similar to the pool pockets and both of your posted examples. I think the problem was not having this line in my code:

zone[i].bullet = false  

When I remove this line objects pass into the zones and no collision events are fired. I need to study the API to learn about bullet and isBullet I guess.

[import]uid: 9977 topic_id: 10626 reply_id: 38625[/import]

yep, I’m setting object IDs and it’s working. I’m able to detect which dynamic objects are within a static zone using this method. Thanks! [import]uid: 9977 topic_id: 10626 reply_id: 38626[/import]