How to match collisions with object data?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
m0nkeybl1tz
Prole
Posts: 14
Joined: Fri Jan 22, 2016 3:25 am

How to match collisions with object data?

Post 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?
User avatar
pgimeno
Party member
Posts: 3548
Joined: Sun Oct 18, 2015 2:58 pm

Re: How to match collisions with object data?

Post 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.
Ross
Citizen
Posts: 98
Joined: Tue Mar 13, 2018 12:12 pm
Contact:

Re: How to match collisions with object data?

Post 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.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 141 guests