About the inaccuracy in collision reports


I’m dealing with collisions for some gameplay tests, and I think I’m getting to this point:

Touching: bool, whether or not the contact is currently touching. ***Due to the way contacts are cached this can be false under some circumstances***

(from the reference, about physics.contact)

Indeed, some contacts are left unreported. Not often, but often enough to make my little prototype frustrating. Is there a way to force the collide function to update itself in order to catch contacts it was previously ignoring?


Are you talking about problems with collisions (the collide function), or currently touching objects?

Also, are your objects moving fast? If so, you may need to turn bullet mode on.

That line in the reference just refers to the touching flag, not the collide function. I only use the collide function. If you need an isTouching flag, you can set it and clear it yourself on collide state began and ended.

A tip, if you don’t already use this method: have a table that indexes your game objects by their physics body.

In the class init:

Body = class() --master class for all physics bodies

bodies = {} --index instances of this class by their physics body

function Body:init()
    local bod = physics.body(CIRCLE, 10)
    bodies[bod] = self

Give the class a collide method:

function Body:collide(c, bod)
    if c.state == BEGAN then
        self.isTouching = true --flag for collision state
        if bodies[bod].category = categories.enemyBullet then --do some tests for what object has collided with
            --deduct some health
    elseif c.state == ENDED then
        self.isTouching = false

Then the global collide function just looks like this:

function collide(c)
    if bodies[c.bodyA] then bodies[c.bodyA]:collide(c, c.bodyB) end --pass the other body (the collide-ee) to the collide-er 
    if bodies[c.bodyB] then bodies[c.bodyB]:collide(c, c.bodyA) end

Hey, thanks to both of you! The objects were very slow, so it wasn’t the tunneling problem… But, I forced:

if contact.state == BEGAN then
    contact.bodyA.touching = true
    contact.bodyB.touching = true

if contact.state == END then
    contact.bodyA.touching = false
    contact.bodyB.touching = false

At the beginning of my collide(contact) function, and it seems to be working now!

I need to test it more, but the problem didn’t happen in a few minutes of gameplay. I’m really happy, thanks so much!

Now I need to fix that crazy Xcode issue so I can send it for review…


It should be ENDED not END

Oh yes, thanks!