Get class name on physic collision

Is there a way to get the class name of a class with physic body?
Here is a solution: Set a property of all classes which using physics. e.g.
self.name = "ball" -- or debug.getinfo(2, "n").name
so it’s done and easy to use in function collide(contact).
if contact.bodyA.parent.name == "ball" then ... end
parent is set to body and contains self.

But I will check the name in collide function withou setting custom properties to every class manually.
Why? It’s useful if you have several bodies with different functions. e.g. Walls, Balls, etc. I won’t create the same properties to every class.

The best way to handle physics collisions is to have a table indexed by the body itself.

So in the class’ init you have:

function box2d:init(t)
  ...
  self.body = physics.body(CIRCLE, 10)
  bodies[self.body] =self
end

function box2d:collided(otherBody, contact)
  ...
end

then your collisions can be resolved with

function collide(contact)
   bodies[contact.bodyA]:collided(contact.bodyB, contact)
   bodies[contact.bodyB]:collided(contact.bodyA, contact)
end

Make sure that at the end of the level you destroy all physics bodies then remove all references to the bodies

Thank you, that is a known technique.

The best place for tips like this is in the wiki at the top, because your thread is going to disappear off the page in a couple of days and be lost.

@Ignatz Huh?

A tip in a forum thread will soon be pushed off the front page by new threads, and get forgotten unless it is carefully tagged so a search will find it

You could maybe improve it by creating a parent class, and then each type of object can inherit from it, and run its own collision code without the need for “if” tests

--parent class
P = class()

function P:init(x,y)
    self.body = physics.body(CIRCLE, 50)
    self.body.parent = self -- or name it "me" or "this" ( necessary to call this object / instance in global collide function)
    self.body.x = x
    self.body.y = y
end

function P:collide(contact)
    --default is to do nothing   
end

--ball child class
Ball = class(P)

function Ball:collide(contact)
    --custom ball collision code
end

--block child class
Block=class(P)

function Block:collide(contact)
    --custom block collision code
end

So what’s the forum for then?

Thanks. But let me show another way: (the best way in my opinion)

function Ball:init(x,y) self.body = physics.body(CIRCLE, 50) self.body.parent = self -- or name it "me" or "this" ( necessary to call this object / instance in global collide function) self.body.x = x self.body.y = y end function Ball:collide(contact) -- code here end

Global:
function collide(contact) contact.bodyA.parent:collide(contact) contact.bodyB.parent:collide(contact) end

asking questions and solving problems, ie temporary issues

also for sharing new ideas, but if you’re just giving general tips like that above, they are better kept in a place where people can find them when they need them. That’s why I began writing blog posts.

I’m not totally sure what’s trying to be done here, but here’s how I determine what’s colliding with what or what action I want to take if there is a collision. I have a function for each object. In this example it just returns a name, but the function could have done anything I wanted. Also, instead of the object name being returned in the function, the name could have been defined in a variable in the ball:init function and the objects function could have done something more useful. I find this easy to use for different objects in collisions.

function setup()
    e1=physics.body(EDGE,vec2(0,0),vec2(WIDTH,0))
        e1.func=function() return "bottom edge" end
    e2=physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
        e2.func=function() return "left edge" end
    e3=physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
        e3.func=function() return "right edge" end
    ba={}  -- table for balls
    for z=1,5 do
        table.insert(ba,ball(z))        
    end
    physics.continuous=true
end

function draw()
    background(40, 40, 50)
    for a,b in pairs(ba) do
        b:draw()
    end
end

function collide(c)
    if c.state==BEGAN then
        b1=c.bodyA.func()     -- just returns the bodyA object name     
        b2=c.bodyB.func()     -- just returns the bodyB object name 
        print(b2.." collided with "..b1)           
    end
end

ball=class()

function ball:init(n)
    self.a=physics.body(CIRCLE,20)
    self.a.x=math.random(WIDTH)
    self.a.y=math.random(HEIGHT)
    self.a.restitution=1
    self.a.number=n
    self.a.func=function() return "ball "..self.a.number end
end

function ball:draw()
    fill(255)
    ellipse(self.a.x,self.a.y,40)
    fill(255,0,0)
    text(self.a.number,self.a.x,self.a.y)
end