I want to find and modify physics objects that my physics objects are touching, recursively.

Hi friends!

Let’s say I have 1 to x displayObjects that i’m generated and dropping onto the screen at random. I then addBody() to them to make them physics objects.

So I’ve got this game that is raining objects, and each of those objects have some properties (let’s say color) that I’ve added to them at random.

On a collision I need to:

 1. know what objects each of the other objects are already touching

 2. recursively perform an operation on these objects

We could take a game like Bejeweled or many of the clones as an example. So if I’m dropping objects onto a screen and they have a random color assigned to them, on collision I’d like to know what objects each object is touching (like a chain), and then compare their properties. Matching color objects would then be destroyed.

Searching the forums I couldn’t find a post specific to my needs (some were close, like telling me if objects were in the space surrounding - but not which objects…), so I tried a homegrown solution of:

on collision store the object I collided with and it’s property into a local object property.

on event.phase “ended”, delete said property.

But I’m finding there is a condition where, if my objects come into contact at multiple points, the “ended” phase doesn’t happen at the right time (it sometimes happens too late). At any rate, there seem to be a bunch of things wrong with this implementation.

Is there a better, more standard way to approach my problem? Have I missed some idiom or library that could help me here? What approach might you take for knowing what objects are touching what objects, and selectively performing operations on all connected objects?

I appreciate the help. Thanks for taking the time to read my post. :slight_smile:

Hi @rcastro,

I think you’re on the right track, but let me clarify a few things about the physics engine. When you simply drop an item on screen (and it overlaps other physics objects that have collision listeners) you must consider the order in which these events happen. If you have one object on screen, and other drops on top of it, you’ll get a collision event (obvious enough). Then, if you drop another object on screen, and it lands over both of those items, you’ll get two more collision events.

Another really important thing to consider is how you process the collisions. If you add “return true” to the end of the collision listener, that effectively stops the chain of collision events following the first one that was created. In other words, you’ll get a response from only the object that was created first. Consider this code:

[lua]

local function collTest( self, event )

   print(“COLLIDE!”, self.id, event.other.id )

   --return true

end

local body1 = display.newRect( 150,400,40,40 )

physics.addBody( body1, “dynamic”, { isSensor=true } )

body1.collision = collTest

body1.id = “BODY1”

body1:addEventListener( “collision”, body1 )

local body2 = display.newRect( 170,400,40,40 )

physics.addBody( body2, “dynamic”, { isSensor=true } )

body2.collision = collTest

body2.id = “BODY2”

body2:addEventListener( “collision”, body2 )

[/lua]

Note that because “return true” is commented out, you get 2 collision events, as in “1-on-2” and “2-on-1”. However, if you un-comment the “return true” like this…

[lua]

local function collTest( self, event )

   print(“COLLIDE!”, self.id, event.other.id )

   return true

end

[/lua]

…you’ll only get 1 response of “1-on-2”.

So really, it’s not that events are happening at the wrong time, it more that you need to consider how you process them, and in what order.

Also, generally speaking, you should use the began phase, not ended to detect collisions. The ended phase is useful when you want to detect an object “un-colliding” with another (which is useful in some cases but less commonly than the first case).

As for your recursive processing needs, I can’t advise specifically on that because I don’t know your game functionality. However, you can “flash” any physics object by making it inactive and then active in two consecutive lines. This will re-trigger a collision between overlapping objects, as if you re-dropped it in the same place. So, using this, you may be able to recursively process a chain of collisions, but it will require some careful handling I think.

Hope this helps,

Brent

Thanks Brent - I will refactor based on your feedback and see where that takes me. To confirm my understanding:

I am using “began” to collect data on what other objects I’m touching, but I’m using “ended” to determine that two objects are no longer touching. Is that logic I can rely on? If a physics event has “ended” does that mean in fact that that collision point is absolutely 100% no longer in contact with the trigger of the collision?

If so, it’s my understanding that there could be multiple collision points for the same object, say the ‘left side’ of Object A touches object B, and then the “right” side of Object A touches Object B before the event for Collision A completes - is this the condition you’re speaking of that could put me in a difficult situation?

I believe it is (and I see now where I need to refactor), but I want to make sure I am understanding your recommendations. :slight_smile:

Thank you for such a verbose and helpful response!

Hi @rcastro,

You’re mostly correct on these points.

The began phase is for when a collision occurs, and ended is for when it un-occurs, i.e. one object either drifts outside or is forcibly moved outside the contact point of another.

As for the second question, it depends on how you’ve constructed your physics bodies. Unless you used multi-element bodies, then there’s not really two “sides” to any object… you’ll only get the normal began and ended phase as described above. However, if you are dealing with multi-element bodies, then absolutely yes, you’ll get a began and ended collision event for each element in each body, and that potentially opens up a whole different can of worms. :slight_smile:

Brent

Just wanted to post an update for interested/future parties. This was just what I needed to solve my troubles. Each object used collision events to keep track of it’s ‘touching’ objects, and that made it easy to perform operations on multiple objects using recursion.

In a related note, I’m really, really, really impressed with Corona SDK. I’ve spent only a few hours of time with Corona and Lua, and I find it’s incredibly powerful.

More importantly than powerful though: It’s incredibly stable. Coming from a few weekend trials of something like PhoneGap, it’s very, very refreshing to see something so stable. I mean, I installed it - and it didn’t error. I didn’t have to deal with Path issues, and I didn’t even have to fight with the JRE or some weird build structure… it just worked!

Also, the documentation is really really concise. I appreciate the effort gone into providing excellent documentation.

The only thing I could find to complain about is Lua. I completely understand why it was selected for the task, but coming from Ruby, I miss the easy language constructs Ruby provides. But like I said… I’m reaching for things to complain about thus far.

Thanks for the help, Brent. Your responsiveness and willingness to help is just another star on the Corona experience.

Hi @rcastro,

I appreciate your comments and I’m glad that Corona is meeting your development needs. Best of luck on your game, and please post to the forums when it goes to the Apple or Google marketplace(s). We’re always curious to see what developers produce using Corona.

Take care,

Brent

Hi @rcastro,

I think you’re on the right track, but let me clarify a few things about the physics engine. When you simply drop an item on screen (and it overlaps other physics objects that have collision listeners) you must consider the order in which these events happen. If you have one object on screen, and other drops on top of it, you’ll get a collision event (obvious enough). Then, if you drop another object on screen, and it lands over both of those items, you’ll get two more collision events.

Another really important thing to consider is how you process the collisions. If you add “return true” to the end of the collision listener, that effectively stops the chain of collision events following the first one that was created. In other words, you’ll get a response from only the object that was created first. Consider this code:

[lua]

local function collTest( self, event )

   print(“COLLIDE!”, self.id, event.other.id )

   --return true

end

local body1 = display.newRect( 150,400,40,40 )

physics.addBody( body1, “dynamic”, { isSensor=true } )

body1.collision = collTest

body1.id = “BODY1”

body1:addEventListener( “collision”, body1 )

local body2 = display.newRect( 170,400,40,40 )

physics.addBody( body2, “dynamic”, { isSensor=true } )

body2.collision = collTest

body2.id = “BODY2”

body2:addEventListener( “collision”, body2 )

[/lua]

Note that because “return true” is commented out, you get 2 collision events, as in “1-on-2” and “2-on-1”. However, if you un-comment the “return true” like this…

[lua]

local function collTest( self, event )

   print(“COLLIDE!”, self.id, event.other.id )

   return true

end

[/lua]

…you’ll only get 1 response of “1-on-2”.

So really, it’s not that events are happening at the wrong time, it more that you need to consider how you process them, and in what order.

Also, generally speaking, you should use the began phase, not ended to detect collisions. The ended phase is useful when you want to detect an object “un-colliding” with another (which is useful in some cases but less commonly than the first case).

As for your recursive processing needs, I can’t advise specifically on that because I don’t know your game functionality. However, you can “flash” any physics object by making it inactive and then active in two consecutive lines. This will re-trigger a collision between overlapping objects, as if you re-dropped it in the same place. So, using this, you may be able to recursively process a chain of collisions, but it will require some careful handling I think.

Hope this helps,

Brent

Thanks Brent - I will refactor based on your feedback and see where that takes me. To confirm my understanding:

I am using “began” to collect data on what other objects I’m touching, but I’m using “ended” to determine that two objects are no longer touching. Is that logic I can rely on? If a physics event has “ended” does that mean in fact that that collision point is absolutely 100% no longer in contact with the trigger of the collision?

If so, it’s my understanding that there could be multiple collision points for the same object, say the ‘left side’ of Object A touches object B, and then the “right” side of Object A touches Object B before the event for Collision A completes - is this the condition you’re speaking of that could put me in a difficult situation?

I believe it is (and I see now where I need to refactor), but I want to make sure I am understanding your recommendations. :slight_smile:

Thank you for such a verbose and helpful response!

Hi @rcastro,

You’re mostly correct on these points.

The began phase is for when a collision occurs, and ended is for when it un-occurs, i.e. one object either drifts outside or is forcibly moved outside the contact point of another.

As for the second question, it depends on how you’ve constructed your physics bodies. Unless you used multi-element bodies, then there’s not really two “sides” to any object… you’ll only get the normal began and ended phase as described above. However, if you are dealing with multi-element bodies, then absolutely yes, you’ll get a began and ended collision event for each element in each body, and that potentially opens up a whole different can of worms. :slight_smile:

Brent

Just wanted to post an update for interested/future parties. This was just what I needed to solve my troubles. Each object used collision events to keep track of it’s ‘touching’ objects, and that made it easy to perform operations on multiple objects using recursion.

In a related note, I’m really, really, really impressed with Corona SDK. I’ve spent only a few hours of time with Corona and Lua, and I find it’s incredibly powerful.

More importantly than powerful though: It’s incredibly stable. Coming from a few weekend trials of something like PhoneGap, it’s very, very refreshing to see something so stable. I mean, I installed it - and it didn’t error. I didn’t have to deal with Path issues, and I didn’t even have to fight with the JRE or some weird build structure… it just worked!

Also, the documentation is really really concise. I appreciate the effort gone into providing excellent documentation.

The only thing I could find to complain about is Lua. I completely understand why it was selected for the task, but coming from Ruby, I miss the easy language constructs Ruby provides. But like I said… I’m reaching for things to complain about thus far.

Thanks for the help, Brent. Your responsiveness and willingness to help is just another star on the Corona experience.

Hi @rcastro,

I appreciate your comments and I’m glad that Corona is meeting your development needs. Best of luck on your game, and please post to the forums when it goes to the Apple or Google marketplace(s). We’re always curious to see what developers produce using Corona.

Take care,

Brent