collision event not firing for dynamic object with static object

Hi,

I have a dynamic object and a static object.  I am moving the static object towards the dynamic object, I need the static object to pass through the dynamic object (as it is a sensor), but when it does there is no physics collision detected on the dynamic object.  But if I change the isSensor property to false in the static property then the collision event fires… has anyone else had this issue?  I assume it should fire when isSensor property is true?

I am using build 2014.2187

here is the code

physics = require( "physics" ) physics.start() physics.setDrawMode( "hybrid" ) local floor = display.newRect(0, 0, 1500, 100) floor.y = 900 physics.addBody(floor, "static") local box = display.newRect(0, 0, 100, 100) box.x = 100 box.y = 800 physics.addBody(box, "dynamic") local sensor = display.newRect(0, 0, 100, 100) sensor.x = 500 sensor.y = 800 physics.addBody(sensor, "static") sensor.isSensor = true function GameLoop() sensor.x = sensor.x - 5 end function CollisionHandler(event) print(event.phase) end box:addEventListener( "collision", CollisionHandler ) Runtime:addEventListener( "enterFrame", GameLoop )

Hi @vik_b_it,

You’re setting up the collision handler improperly. It should be this (for “local” type collisions, not global):

[lua]

box.collision = CollisionHandler

box:addEventListener( “collision”, box )

[/lua]

And, the handler function will need the “self” parameter, like this:

[lua]

function CollisionHandler( self, event )  --‘self’ will be the reference to the box

   print( event.phase )

end

[/lua]

All of this is outlined in the Collisions guide here:

http://docs.coronalabs.com/guide/physics/collisionDetection/index.html

Best regards,

Brent

Brent,

It still doesn’t work…

here is the code with your changes

physics = require( "physics" ) physics.start() physics.setDrawMode( "hybrid" ) local floor = display.newRect(0, 0, 1500, 100) floor.y = 900 physics.addBody(floor, "static") local box = display.newRect(0, 0, 100, 100) box.x = 100 box.y = 800 physics.addBody(box, "dynamic") local sensor = display.newRect(0, 0, 100, 100) sensor.x = 500 sensor.y = 800 physics.addBody(sensor, "static") sensor.isSensor = true function GameLoop() sensor.x = sensor.x - 5 end function CollisionHandler( self, event ) --'self' will be the reference to the box print( event.phase ) end box.collision = CollisionHandler box:addEventListener( "collision", box ) Runtime:addEventListener( "enterFrame", GameLoop )

also just to clarify, in the first set of code I posted, I am not adding a global collision type, as I am not adding to the runtime

I’m not sure what’s going on… this code is structured exactly as stated under “Local Collision Handling” in this guide:

http://docs.coronalabs.com/guide/physics/collisionDetection/index.html

I’ve used this code structure many, many times, and it always works. The only tiny difference I see is that your “CollisionHandler” function is global, but I don’t think should cause a no-response issue.

Brent

Brent,

Looks like I need to keep my dynamic object active all the time, the reason its getting no collision is because it is going to sleep.  In my code if I add in

function GameLoop() sensor.x = sensor.x - 5 --print(box.isAwake) box.isAwake = true end

then I get a collision.  But I wouldn’t have thought I had to keep it awake… maybe I am missing something…

This is expected behavior. Unless a body receives some kind of physical input, it will go to sleep after a few seconds. You can force it to stay awake by using the following (instead of continually setting it to awake in the GameLoop function):

[lua]

myBody.isSleepingAllowed = false

[/lua]

http://docs.coronalabs.com/api/type/Body/isSleepingAllowed.html

Have fun!

Brent

Brent,

Quick question…

I am using classes as shown…

local Character = class('Character') function Character:initialize(view, params) self.\_view = view self:AddEventListeners() end function Character:FlyEvent(event) print('fly') end function Character:DestroyEvent(event) self:RemoveEventListeners() end function Character:CollisionHandler(event) --some code end function Character:AddEventListeners() self.\_character:addEventListener("collision", function(e) self:CollisionHandler(e) end ) end function Character:RemoveEventListeners() self.\_character:removeEventListener("collision", function(e) self:CollisionHandler(e) end ) end return Character

I have added event listners for the collision, but my question is how do I set it up like you have shown above?

box.collision = CollisionHandler box:addEventListener( "collision", box )

as it doesn’t work…

Thanks

You cannot use anonymous functions/closures like this for adding and removing event listeners:

self._character:addEventListener(“collision”, function(e) self:CollisionHandler(e) end )

The reason for this is that addEventListener stores the address of the function in a table to later reference on the remove step.  The two functions, while coded identically have a different address in memory and therefore do not match when you go to do the remove.  You must have a normal function and use the function name in these cases.

Rob

Hi @vik_b_it,

You’re setting up the collision handler improperly. It should be this (for “local” type collisions, not global):

[lua]

box.collision = CollisionHandler

box:addEventListener( “collision”, box )

[/lua]

And, the handler function will need the “self” parameter, like this:

[lua]

function CollisionHandler( self, event )  --‘self’ will be the reference to the box

   print( event.phase )

end

[/lua]

All of this is outlined in the Collisions guide here:

http://docs.coronalabs.com/guide/physics/collisionDetection/index.html

Best regards,

Brent

Brent,

It still doesn’t work…

here is the code with your changes

physics = require( "physics" ) physics.start() physics.setDrawMode( "hybrid" ) local floor = display.newRect(0, 0, 1500, 100) floor.y = 900 physics.addBody(floor, "static") local box = display.newRect(0, 0, 100, 100) box.x = 100 box.y = 800 physics.addBody(box, "dynamic") local sensor = display.newRect(0, 0, 100, 100) sensor.x = 500 sensor.y = 800 physics.addBody(sensor, "static") sensor.isSensor = true function GameLoop() sensor.x = sensor.x - 5 end function CollisionHandler( self, event ) --'self' will be the reference to the box print( event.phase ) end box.collision = CollisionHandler box:addEventListener( "collision", box ) Runtime:addEventListener( "enterFrame", GameLoop )

also just to clarify, in the first set of code I posted, I am not adding a global collision type, as I am not adding to the runtime

I’m not sure what’s going on… this code is structured exactly as stated under “Local Collision Handling” in this guide:

http://docs.coronalabs.com/guide/physics/collisionDetection/index.html

I’ve used this code structure many, many times, and it always works. The only tiny difference I see is that your “CollisionHandler” function is global, but I don’t think should cause a no-response issue.

Brent

Brent,

Looks like I need to keep my dynamic object active all the time, the reason its getting no collision is because it is going to sleep.  In my code if I add in

function GameLoop() sensor.x = sensor.x - 5 --print(box.isAwake) box.isAwake = true end

then I get a collision.  But I wouldn’t have thought I had to keep it awake… maybe I am missing something…

This is expected behavior. Unless a body receives some kind of physical input, it will go to sleep after a few seconds. You can force it to stay awake by using the following (instead of continually setting it to awake in the GameLoop function):

[lua]

myBody.isSleepingAllowed = false

[/lua]

http://docs.coronalabs.com/api/type/Body/isSleepingAllowed.html

Have fun!

Brent

Brent,

Quick question…

I am using classes as shown…

local Character = class('Character') function Character:initialize(view, params) self.\_view = view self:AddEventListeners() end function Character:FlyEvent(event) print('fly') end function Character:DestroyEvent(event) self:RemoveEventListeners() end function Character:CollisionHandler(event) --some code end function Character:AddEventListeners() self.\_character:addEventListener("collision", function(e) self:CollisionHandler(e) end ) end function Character:RemoveEventListeners() self.\_character:removeEventListener("collision", function(e) self:CollisionHandler(e) end ) end return Character

I have added event listners for the collision, but my question is how do I set it up like you have shown above?

box.collision = CollisionHandler box:addEventListener( "collision", box )

as it doesn’t work…

Thanks

You cannot use anonymous functions/closures like this for adding and removing event listeners:

self._character:addEventListener(“collision”, function(e) self:CollisionHandler(e) end )

The reason for this is that addEventListener stores the address of the function in a table to later reference on the remove step.  The two functions, while coded identically have a different address in memory and therefore do not match when you go to do the remove.  You must have a normal function and use the function name in these cases.

Rob