Page 1 of 1

How to match collisions with object data?

Posted: Mon Jan 10, 2022 8:54 pm
by m0nkeybl1tz
Hey all, I'm trying to make a basic top down game, and part of that is detecting collisions. However, depending on the object collided with, I want different behaviors. For example, if the player collides with a box, I want to destroy the box. If they collide with an enemy, I want them to take damage. If they collide with a building, I want them to stop moving. I come from the OOP world, so I was imagining implementing it something like this:

Code: Select all

function OnCollision(collideObject)
    if (collideObject.type == box) then
        collideObject.Destroy()
    end
    if (collideObject.type == enemy) then
        player.TakeDamage()
    end
    if (collideObject.type == building) then
        player.Stop()
    end
I've implemented some basic collision detection, and I suppose I could iterate through every object every frame to see if there's a collision with it, but I imagine that will get expensive with lots of objects. I was thinking of implementing a physics library like HC, breezefield, etc. to do more efficient collisions, but I'm not sure if there's a way to get a reference to the original object, not just its collider. For example, if I created a box using something like:

Code: Select all

newBox = {x=100,y=100,type="box",collider=SomeColliderFunction}
and the box's collider was involved with a collision, how would I get a reference to the box object itself?

Re: How to match collisions with object data?

Posted: Mon Jan 10, 2022 11:16 pm
by pgimeno
Thankfully, table indexes can be objects. This means you can construct a cross-reference table (maybe with weak keys, up to you) that stores the object each fixture belongs to. You just need to add a preprocessing step to your game objects; in pseudocode:

Code: Select all

local objFromFixture = {}

for i = 1, #objects do
  for j = 1, #objects[i].fixtures do
    objFromFixture[objects[i].fixtures[j]] = objects[i]
  end
end
Now, given a fixture (via the beginContact/endContact world callbacks) you can find out which object it belongs to by looking up the fixture in objFromFixture (objFromFixture[fixture] is the object the fixture belongs to).

Of course, if you add/destroy objects you also need to update the table accordingly. If the keys are weak, you don't need to update it on deletion, only on addition of new objects.

Re: How to match collisions with object data?

Posted: Tue Jan 11, 2022 3:55 pm
by Ross
I use fixture:setUserData() when creating fixtures to store a reference to my object on the fixture. And then retrieve it in the collision handler with fixture:getUserData(). You can do the same with Body.