Collision Handler "ended" phase not triggered

I have two physics bodies

Player:  

physics.addBody(
    gc.player.sprite, “dynamic”,
    { density = 35, friction = 0.1, bounce = 0 , shape = polyBody},
  );

Snake:

physics.addBody(enemy.sprite, “static”, { density = 1, friction = 0, bounce = 0, isSensor = true });

The snake is moving and the player isn’t moving

When the snake collides with the player, a collision event with the “began” phase is triggered.

However when the snake moves past the player, no collision event with the “ended” phase is triggered

How do I fix this?

Can you post how you’re setting up your collision handlers?    Also, why is the static snake moving and why do you have it as a sensor?

I set the snake as a sensor so that the player sprite can move past it. For some reason, if I set the snake as a dynamic body with isSensor = true, the snake falls through the ground (even though the ground is a physics body). Setting the snake as a static body fixed this for some reason.

I handled the collisions by adding a collision handler to Runtime.

Read this:

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

The Documentation says:

“began” and"ended" collision events are still fired

So I’m still not sure what is wrong

isSensor makes the body not react to physics, so it will pass through other physics objects.    You’ll get the began and ended, but in the physics world of the game it won’t “collide”.

Is that what you want?    

There’s a good reason to set objects as sensors.   For example, I do with my ice cubes that are waiting to be launched, so flying objects don’t hit them.   I then turn it off for the cube when the player launches it so that it can collide with glasses, rocks, etc.

Yeah that’s what I want. I want the snake to trigger the began and ended phases, but not react to hitting the player. Thats why isSensor = true. But what I don’t understand is why the ended phase of the “collision” is not being triggered (but the “began” phase is).

Can you post your collision handlers?

@atrizhong You need to post more code - you’re stating a problem with collisions but not posting any collision handling code. @davemikesell is correct to ask.

Having said that, if your collision listener is using the event.contact value to disable the collision, you might simply have a typo which is messing things up.

http://coronalabs.com/blog/2012/11/27/introducing-physics-event-contact/

I suspect a simple typo or logical bug, but post more code and we can see.

function gc:collision(inEvent) print("Phase: " .. inEvent.phase);   -- Determining which object hit the player   local otherObject;   if (inEvent.object1.name ~= "player" and inEvent.object2.name ~= "player") then return end   if (inEvent.object1.name == "player") then     otherObject = inEvent.object2;   else     otherObject = inEvent.object1;   end   --Handle player collisions with chest   if (otherObject.name == "chest") then          if inEvent.phase == "began" then             local alreadyTouching = false;             for i = 1, #gc.player.touchChests, 1 do                 if gc.player.touchChests[i] == otherObject then                     alreadyTouching = true;                     break;                 end             end             if not alreadyTouching then                 table.insert(gc.player.touchChests, otherObject);             end           elseif inEvent.phase == "ended" then             for i = 1, #gc.player.touchChests, 1 do                 if gc.player.touchChests[i] == otherObject then                     table.remove(gc.player.touchChests, i);                 end             end       end   --Handle collisions with snake   elseif (otherObject.name == "snake") then        print("Phase: " .. inEvent.phase);        if inEvent.phase == "began" then             local alreadyTouching = false;             for i = 1, #gc.player.touchEnemies, 1 do                 if gc.player.touchEnemies == otherObject then                     alreadyTouching = true;                     break;                 end             end             if not alreadyTouching then                 table.insert(gc.player.touchEnemies, otherObject);             end           elseif inEvent.phase == "ended" then             for i = 1, #gc.player.touchEnemies, 1 do                 if gc.player.touchEnemies[i] == otherObject then                     table.remove(gc.player.touchEnemies, i);                 end             end       end     end   end -- End touch().  

Note that as I said earlier, I added the collision handler to Runtime, if that makes any difference.

Hmmm…I can see anything wrong, though I would probably implement these as local collision handlers.

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

Are you sure the name is “snake” and not “Snake”?    What are you doing to the objects that are touching the snake?   

Yes the name is “snake”.

Pretty much what this code is doing is that whenever the snake is touching the player, the snake is added to a table called touchEnemies (which is pretty much a table containing all of the enemies that the player is currently touching). When the snake stops touching the player, it should be removed from the touchEnemies table. However, since the “ended” phase is never called, the snake cannot be removed from the touchEnemies table.

For some reason, if the player stays still and the snake moves past him, then the collision event “began” is fired but “ended” isn’t fired even when the snake moves past the player. Only after the player moves is the “ended” event fired, which is pretty strange. The following pictures may give a clearer understanding of my dilemma:

DURING COLLISION:

http://imgur.com/JTOkTO1,CAm4lUg,LU2Jwwq#0

AFTER COLLISION (NOTICE “ENDED” PHASE ISN’T FIRED):

http://imgur.com/JTOkTO1,CAm4lUg,LU2Jwwq#1

ONLY AFTER THE PLAYER MOVES IS THE ENDED PHASE FIRED:

http://imgur.com/JTOkTO1,CAm4lUg,LU2Jwwq#2

Definitely rewrite with local collision listeners. Build a much simpler version of what you’re doing and then see how the critical parts compare.

Thanks for the help guys, but I found the solution. I set the player’s isSleepingAllowed property (a physics body property) to false. This seems to allow the player to detect the ended collision phase. I noticed this when i turned the physics draw mode to hybrid and saw that the player’s physic body became inactive after colliding with the snake