Page 1 of 1

Method for getting parent/sibling

Posted: Tue Aug 28, 2012 12:07 am
by Knaimhe
This concerns Box2D.
I've got my bodies/shapes/fixtures in tables, like so:
Objects = {}
Objects.thingy = {}
Objects.thingy.body = love.physics.newBody(bodyargs)
Objects.thingy.shape = love.physics.newRectangleShape(shapeargs)
Objects.thingy.fixt = love.physics.newFixture(fixtargs)

I have a collision callback that returns the fixtures in contact.
The callback also calls a function which uses both the thingy's fixture and the thingy's body.
Unfortunately, I can't find a method that returns the parent (Objects.thingy) or a sibling (Objects.body).
Is there one?

(Note: There are multiple copies of Object.thingy. Yes, several thingies bouncin' about on-screen. So I can't call anything by name, for instance.)

Re: Method for getting parent/sibling

Posted: Tue Aug 28, 2012 1:30 am
by Knaimhe
Nevemind! I discovered Fixture:getBody().

Re: Method for getting parent/sibling

Posted: Tue Sep 04, 2012 5:19 pm
by tormentor32
Hey Guys,

i have a problem that goes in the same direction:

I have an array of balls, and I want a ball to change color, whenever it collides with the wall. My func addBall looks like this:

Code: Select all

function addBall(x, y)
	balls[ballcount] = {}
	balls[ballcount].body = love.physics.newBody(world, x, y, "dynamic") 
	balls[ballcount].shape = love.physics.newCircleShape(32)
	balls[ballcount].fixture = love.physics.newFixture(balls[ballcount].body, balls[ballcount].shape, 1)
	balls[ballcount].fixture:setRestitution(0.75)
	balls[ballcount].fixture:setUserData("Ball")
	balls[ballcount].r = math.random(255)
	balls[ballcount].g = math.random(255)
	balls[ballcount].b = math.random(255)
	ballcount = ballcount+1
end
But I don't know how to get/change these values in the callback function:

Code: Select all

function beginContact(a, b, coll)
	if
		((b:getUserData() == "Ball" or a:getUserData() == "Ball")
		and (b:getUserData() ~= "Plank" and a:getUserData() ~= "Plank"
		and b:getUserData() ~= "Bottom" and a:getUserData() ~= "Bottom"))
	then
		colorr = math.random(100)
		colorg = math.random(100)
		colorb = math.random(100)

-- I was using a globale var before I started to use multible Balls.

		hits = hits + 1
	end
--...
Is there any way to solve that problem? Even if I made another array that stores the additional info about the objects, I still have the problem how to get the info connected to the object...

Thanks for your help!

Re: Method for getting parent/sibling

Posted: Wed Sep 05, 2012 7:42 am
by bartoleo
I add the object in the userdata like this:

Code: Select all

balls[ballcount].fixture:setUserData({type="Ball",value=balls[ballcount]})
and in the collision callback
first I have 2 functions for easy work on the two userdata

Code: Select all

function testCollision(userdata1,userdata2,attribute,test1,test2) 
  if (userdata1[attribute]==test1 and userdata2[attribute]==test2) then
    return true
  elseif (userdata1[attribute]==test2 and userdata2[attribute]==test1) then
    return true
  end
  return false
end

function getCollisionObject(userdata1,userdata2,attribute,test) 
  if userdata1[attribute]==test then
    return userdata1
  elseif userdata2[attribute]==test then
    return userdata2
  end
  return nil
end
with this I can test for collision between Ball and Plank
and access the Ball object

Code: Select all

  local userdata1 = a:getUserData()
  local userdata2 = b:getUserData()
  if testCollision(userdata1,userdata2,"type","Ball","Plank") then
    local userdataball = getCollisionObject(userdata1,userdata2,"type","Ball") 
    --- and then you can access Ball object via userdataball.value
  end 
I hope this will help you

Re: Method for getting parent/sibling

Posted: Wed Sep 05, 2012 5:53 pm
by tormentor32
Thanks a lot! That works perfectly!