Collision detection?

My collision detection function works when a “block” I created collides with any other physics object, which triggers an overlay. How can I make it that the overlay is only triggered when the “block” collides with a specific physics body only, not every physics body.

Cheers

Hey darkspike,

first of all you should make sure to use a local collision listener instead of a global one (add the listener to the “block” in your case and not to the runtime), if you are not already doing so.

To determine which object collides with the block, you could give each physic object a custom field, which contains its collision type (this is an arbitary value, work out a system that works for you). Here’s a simple example.

local block = display.newRect(0,0,40,40) physics.addBody(block, "dynamic", {density=1, friction=0, bounce=0}) local wall = display.newRect(100,0,10,400) physics.addBody(wall, "static", {density=1, friction=0, bounce=0}) wall.collisionType = "wall" local ground = display.newRect(0,50,400,10) physics.addBody(ground, "static", {density=1, friction=0, bounce=0}) ground.collisionType = "ground" local blockCollision(event) local phase = event.phase local targe = event.target local other = event.other if phase == "began" then if other.collisionType == "wall" then --do something end end end block:addEventListener("collision", blockCollision)

In this example there will only happen something, if the block hits the wall, but not if it hits the floor.

Hope that helps.

Greetings

Torben

Hi Torben, this doesn’t seem to be working, I followed your template exactly but I keep getting a syntax error on the line where it says “local phase = event.phase.” Here is my code, maybe I am missing something?

local ground = display.newRect(display.contentCenterX, display.contentHeight\*1.04, display.contentWidth, display.contentHeight\*.05) physics.addBody(ground, "static", {bounce = 0}) ground.collisionType = "ground" local roof = display.newRect(display.contentCenterX, display.contentHeight\*1.04, display.contentWidth\*3, display.contentHeight\*.05) roof.x = 200 roof.y = -8 physics.addBody(roof, "static", {bounce = 0}) roof.collisionType = "roof" local eggplant = display.newImageRect( scene.perRunGroup, "images/eggplant.png", 50, 50, display.contentCenterX, display.contentCenterY, 30) eggplant.x = 70 eggplant.y = 100 physics.addBody(eggplant, "dynamic", {radius = 25, friction = .4, density = 0.0035, bounce = 0.8}) eggplant.gravityScale = 0.5 eggplant.collisionType = "eggplant" local goal = display.newImageRect( scene.perRunGroup, "images/block.jpg", 70, 70, display.contentCenterX, display.contentCenterY, 30) goal.x = 250 goal.y = 200 physics.addBody(goal, "dynamic", {friction = .4, density = 200000000, bounce = 0}) goal.gravityScale = 0 goal.collisionType = "goal" --------------------------Collision Event local goalCollision(event) local phase = event.phase local target = event.target local other = event.other if phase == "began" then if other.collisionType == "eggplant" then end end end goal:addEventListener("collision", goalCollision)

Cheers

Hey,

yeah sorry, it has to be:

local function goalCollision(event)

Just missed the function declaration.

While @torbenratzlaff’s solution will certainly work and it’s pretty simple to check a flag and either do something or ignore the collision event, it’s still processing the collision which is a bit of a performance issue.

The preferred way, although a bit more complex is to use Collision Filters. With this you can tell the physics engine to not process collisions when two egg plants hit each other.

See: https://docs.coronalabs.com/guide/physics/collisionDetection/index.html#filtering

Rob

Thanks Rob! How much of a performance issue would it really be, there’s only ever a small number of objects that the eggplant will actually be colliding with, maybe 3-4.

Small number, small impact, large number of items larger impact.

But loose code now means more and harder work later.

Rob

Hey darkspike,

first of all you should make sure to use a local collision listener instead of a global one (add the listener to the “block” in your case and not to the runtime), if you are not already doing so.

To determine which object collides with the block, you could give each physic object a custom field, which contains its collision type (this is an arbitary value, work out a system that works for you). Here’s a simple example.

local block = display.newRect(0,0,40,40) physics.addBody(block, "dynamic", {density=1, friction=0, bounce=0}) local wall = display.newRect(100,0,10,400) physics.addBody(wall, "static", {density=1, friction=0, bounce=0}) wall.collisionType = "wall" local ground = display.newRect(0,50,400,10) physics.addBody(ground, "static", {density=1, friction=0, bounce=0}) ground.collisionType = "ground" local blockCollision(event) local phase = event.phase local targe = event.target local other = event.other if phase == "began" then if other.collisionType == "wall" then --do something end end end block:addEventListener("collision", blockCollision)

In this example there will only happen something, if the block hits the wall, but not if it hits the floor.

Hope that helps.

Greetings

Torben

Hi Torben, this doesn’t seem to be working, I followed your template exactly but I keep getting a syntax error on the line where it says “local phase = event.phase.” Here is my code, maybe I am missing something?

local ground = display.newRect(display.contentCenterX, display.contentHeight\*1.04, display.contentWidth, display.contentHeight\*.05) physics.addBody(ground, "static", {bounce = 0}) ground.collisionType = "ground" local roof = display.newRect(display.contentCenterX, display.contentHeight\*1.04, display.contentWidth\*3, display.contentHeight\*.05) roof.x = 200 roof.y = -8 physics.addBody(roof, "static", {bounce = 0}) roof.collisionType = "roof" local eggplant = display.newImageRect( scene.perRunGroup, "images/eggplant.png", 50, 50, display.contentCenterX, display.contentCenterY, 30) eggplant.x = 70 eggplant.y = 100 physics.addBody(eggplant, "dynamic", {radius = 25, friction = .4, density = 0.0035, bounce = 0.8}) eggplant.gravityScale = 0.5 eggplant.collisionType = "eggplant" local goal = display.newImageRect( scene.perRunGroup, "images/block.jpg", 70, 70, display.contentCenterX, display.contentCenterY, 30) goal.x = 250 goal.y = 200 physics.addBody(goal, "dynamic", {friction = .4, density = 200000000, bounce = 0}) goal.gravityScale = 0 goal.collisionType = "goal" --------------------------Collision Event local goalCollision(event) local phase = event.phase local target = event.target local other = event.other if phase == "began" then if other.collisionType == "eggplant" then end end end goal:addEventListener("collision", goalCollision)

Cheers

Hey,

yeah sorry, it has to be:

local function goalCollision(event)

Just missed the function declaration.

While @torbenratzlaff’s solution will certainly work and it’s pretty simple to check a flag and either do something or ignore the collision event, it’s still processing the collision which is a bit of a performance issue.

The preferred way, although a bit more complex is to use Collision Filters. With this you can tell the physics engine to not process collisions when two egg plants hit each other.

See: https://docs.coronalabs.com/guide/physics/collisionDetection/index.html#filtering

Rob

Thanks Rob! How much of a performance issue would it really be, there’s only ever a small number of objects that the eggplant will actually be colliding with, maybe 3-4.

Small number, small impact, large number of items larger impact.

But loose code now means more and harder work later.

Rob