Stuck with physics properties - Racing game

Hi guys, currently I’m working on my new racing game which depends a lot on physics. I’m still in process of learning physics engine so I’ve started with simple Billy cart game.

http://developer.coronalabs.com/code/billy-cart-corona

When I tried to insert image of car and wheels(instead of rectangle and wheels) and adjusted rectangle/circle shape to the image, my car aren’t working as they used to. Car body is always falling down and I’m pretty sure that the problem is within physics properties(density).

I’ve tried to change density but I cannot get the same result.

So my question is how do you adjust physics properties like density, linear damping, angular damping, friction etc.? I’m really stuck with physics.

Thanks in advance!

I’ll be more specific. Here is the code that creates the car:

function setupCar(carPositionX, carPositionY) ------------------------------------------- -------------creating car parts------------ ------------------------------------------- --car body carBody = display.newRect(0, 0, 102, 20); carBody:setFillColor(0, 0, 255); --wheels wheelLeft = display.newCircle( 0, 0, 16 ); wheelRight = display.newCircle( 0, 0, 16 ); --base shockBaseLeft = display.newRect(0, 0, 14, 14); shockBaseRight = display.newRect(0, 0, 14, 14); --shock lowerShockLeft = display.newRect(0, 0, 8, 28); lowerShockRight = display.newRect(0, 0, 8, 28); ------------------------------------------- --setting position of elements ------------------------------------------- carBody.x = carPositionX; carBody.y = carPositionY+10; wheelLeft.x = carPositionX-40; wheelLeft.y = carPositionY+20; wheelRight.x = carPositionX+40; wheelRight.y = carPositionY+20; shockBaseLeft.x = carPositionX-40; shockBaseLeft.y = carPositionY+16; shockBaseRight.x = carPositionX+40; shockBaseRight.y = carPositionY+16; lowerShockLeft.x = carPositionX-40; lowerShockLeft.y = carPositionY+24; lowerShockRight.x = carPositionX+40; lowerShockRight.y = carPositionY+24; ------------------------------------------- --inserting elements into group ------------------------------------------- grpMainGroup:insert(carBody); grpMainGroup:insert(wheelLeft); grpMainGroup:insert(wheelRight); grpMainGroup:insert(shockBaseLeft); grpMainGroup:insert(shockBaseRight); grpMainGroup:insert(lowerShockLeft); grpMainGroup:insert(lowerShockRight); ------------------------------------------- --adding physics properties ------------------------------------------- physics.addBody(carBody, {density=0.5, bounce = 0, friction = 0, filter={groupIndex=-1} }); physics.addBody(wheelLeft, {density=0.9, bounce = 0.0, friction = 4.0, radius=16, filter={categoryBits=2,maskBits=1}}); physics.addBody(wheelRight, {density=0.9, bounce = 0.0, friction = 4.0, radius=16, filter={categoryBits=2,maskBits=1}}); physics.addBody(shockBaseLeft, {density=0.05, bounce = 0, friction = 0, filter={groupIndex=-1}}); physics.addBody(shockBaseRight, {density=0.05, bounce = 0, friction = 0, filter={groupIndex=-1}}); physics.addBody(lowerShockLeft, {density=0.02, bounce = 0, friction = 0, filter={groupIndex=-1}}); physics.addBody(lowerShockRight, {density=0.02, bounce = 0, friction = 0, filter={groupIndex=-1}}); ------------------------------------------- --creating joints ------------------------------------------- shockBaseLeftJoint = physics.newJoint ("weld", carBody, shockBaseLeft, shockBaseLeft.x, shockBaseLeft.y); shockBaseRightJoint = physics.newJoint ("weld", carBody, shockBaseRight, shockBaseRight.x, shockBaseRight.y); lowerShockLeftJoint = physics.newJoint ("piston", shockBaseLeft, lowerShockLeft, shockBaseLeft.x, shockBaseLeft.y, 0, 10); lowerShockRightJoint = physics.newJoint ("piston", shockBaseRight, lowerShockRight, shockBaseRight.x, shockBaseRight.y, 0, 10); lowerConnectorLeftJoint = physics.newJoint ("weld",shockBaseLeft, lowerShockLeft, shockBaseLeft.x, shockBaseLeft.y); lowerConnectorRightJoint = physics.newJoint ("weld", shockBaseRight, lowerShockRight, shockBaseRight.x, shockBaseRight.y); wheelLowerLeftJoint = physics.newJoint ("pivot",lowerShockLeft, wheelLeft, wheelLeft.x, wheelLeft.y); wheelLowerRightJoint = physics.newJoint ("pivot", lowerShockRight, wheelRight, wheelRight.x, wheelRight.y); wheelConnectorJoint = physics.newJoint("distance", wheelLeft, wheelRight, wheelLeft.x, wheelLeft.y, wheelRight.x, wheelRight.y); wheelLowerLeftJoint.isMotorEnabled = true wheelLowerLeftJoint.motorSpeed = 0 wheelLowerLeftJoint.maxMotorTorque = 100000 wheelLowerRightJoint.isMotorEnabled = true wheelLowerRightJoint.motorSpeed = 0 wheelLowerRightJoint.maxMotorTorque = 100000 carBody.angularDamping = 50 shockBaseLeft.linearDamping = 10 shockBaseRight.linearDamping = 10 lowerShockLeft.angularDamping = 50 lowerShockRight.angularDamping = 50 lowerShockLeft.linearDamping = 50 lowerShockRight.linearDamping = 50 end

If I increase Car body rectangle height on 40 then my body will fall on the ground. So my question would be how do you calculate new value of density for increased car body?

I think in Box2D the mass is simply calculated based on density and area. So if two objects have the same density, and one has an area twice as large as the other, the larger object will also have twice the mass. In your case, if you’re increasing the height of the car from 20 to 40, you’re doubling its area, so if you want its mass to remain the same, you have to half the density.

That said… in general, certain physics joints tend to break if the objects’ densities vary too much. For example, in your code wheelLeft has a 45 times higher density than lowerShockLeft, which is a very large difference.

Thanks @memo.

Somehow I successfully set right values for my new car. I’ve divided height and width of car parts with 30(because physics scale is set to 30), then calculated area of body. Then I’ve divided mass value(object.mass of my “old” car - car that worked good) with area of body in order to get value of density. Not the best solution but solved my current problem.

But stil, I have to do a lot of work on learnig box2d and physics. 

I’ll be more specific. Here is the code that creates the car:

function setupCar(carPositionX, carPositionY) ------------------------------------------- -------------creating car parts------------ ------------------------------------------- --car body carBody = display.newRect(0, 0, 102, 20); carBody:setFillColor(0, 0, 255); --wheels wheelLeft = display.newCircle( 0, 0, 16 ); wheelRight = display.newCircle( 0, 0, 16 ); --base shockBaseLeft = display.newRect(0, 0, 14, 14); shockBaseRight = display.newRect(0, 0, 14, 14); --shock lowerShockLeft = display.newRect(0, 0, 8, 28); lowerShockRight = display.newRect(0, 0, 8, 28); ------------------------------------------- --setting position of elements ------------------------------------------- carBody.x = carPositionX; carBody.y = carPositionY+10; wheelLeft.x = carPositionX-40; wheelLeft.y = carPositionY+20; wheelRight.x = carPositionX+40; wheelRight.y = carPositionY+20; shockBaseLeft.x = carPositionX-40; shockBaseLeft.y = carPositionY+16; shockBaseRight.x = carPositionX+40; shockBaseRight.y = carPositionY+16; lowerShockLeft.x = carPositionX-40; lowerShockLeft.y = carPositionY+24; lowerShockRight.x = carPositionX+40; lowerShockRight.y = carPositionY+24; ------------------------------------------- --inserting elements into group ------------------------------------------- grpMainGroup:insert(carBody); grpMainGroup:insert(wheelLeft); grpMainGroup:insert(wheelRight); grpMainGroup:insert(shockBaseLeft); grpMainGroup:insert(shockBaseRight); grpMainGroup:insert(lowerShockLeft); grpMainGroup:insert(lowerShockRight); ------------------------------------------- --adding physics properties ------------------------------------------- physics.addBody(carBody, {density=0.5, bounce = 0, friction = 0, filter={groupIndex=-1} }); physics.addBody(wheelLeft, {density=0.9, bounce = 0.0, friction = 4.0, radius=16, filter={categoryBits=2,maskBits=1}}); physics.addBody(wheelRight, {density=0.9, bounce = 0.0, friction = 4.0, radius=16, filter={categoryBits=2,maskBits=1}}); physics.addBody(shockBaseLeft, {density=0.05, bounce = 0, friction = 0, filter={groupIndex=-1}}); physics.addBody(shockBaseRight, {density=0.05, bounce = 0, friction = 0, filter={groupIndex=-1}}); physics.addBody(lowerShockLeft, {density=0.02, bounce = 0, friction = 0, filter={groupIndex=-1}}); physics.addBody(lowerShockRight, {density=0.02, bounce = 0, friction = 0, filter={groupIndex=-1}}); ------------------------------------------- --creating joints ------------------------------------------- shockBaseLeftJoint = physics.newJoint ("weld", carBody, shockBaseLeft, shockBaseLeft.x, shockBaseLeft.y); shockBaseRightJoint = physics.newJoint ("weld", carBody, shockBaseRight, shockBaseRight.x, shockBaseRight.y); lowerShockLeftJoint = physics.newJoint ("piston", shockBaseLeft, lowerShockLeft, shockBaseLeft.x, shockBaseLeft.y, 0, 10); lowerShockRightJoint = physics.newJoint ("piston", shockBaseRight, lowerShockRight, shockBaseRight.x, shockBaseRight.y, 0, 10); lowerConnectorLeftJoint = physics.newJoint ("weld",shockBaseLeft, lowerShockLeft, shockBaseLeft.x, shockBaseLeft.y); lowerConnectorRightJoint = physics.newJoint ("weld", shockBaseRight, lowerShockRight, shockBaseRight.x, shockBaseRight.y); wheelLowerLeftJoint = physics.newJoint ("pivot",lowerShockLeft, wheelLeft, wheelLeft.x, wheelLeft.y); wheelLowerRightJoint = physics.newJoint ("pivot", lowerShockRight, wheelRight, wheelRight.x, wheelRight.y); wheelConnectorJoint = physics.newJoint("distance", wheelLeft, wheelRight, wheelLeft.x, wheelLeft.y, wheelRight.x, wheelRight.y); wheelLowerLeftJoint.isMotorEnabled = true wheelLowerLeftJoint.motorSpeed = 0 wheelLowerLeftJoint.maxMotorTorque = 100000 wheelLowerRightJoint.isMotorEnabled = true wheelLowerRightJoint.motorSpeed = 0 wheelLowerRightJoint.maxMotorTorque = 100000 carBody.angularDamping = 50 shockBaseLeft.linearDamping = 10 shockBaseRight.linearDamping = 10 lowerShockLeft.angularDamping = 50 lowerShockRight.angularDamping = 50 lowerShockLeft.linearDamping = 50 lowerShockRight.linearDamping = 50 end

If I increase Car body rectangle height on 40 then my body will fall on the ground. So my question would be how do you calculate new value of density for increased car body?

I think in Box2D the mass is simply calculated based on density and area. So if two objects have the same density, and one has an area twice as large as the other, the larger object will also have twice the mass. In your case, if you’re increasing the height of the car from 20 to 40, you’re doubling its area, so if you want its mass to remain the same, you have to half the density.

That said… in general, certain physics joints tend to break if the objects’ densities vary too much. For example, in your code wheelLeft has a 45 times higher density than lowerShockLeft, which is a very large difference.

Thanks @memo.

Somehow I successfully set right values for my new car. I’ve divided height and width of car parts with 30(because physics scale is set to 30), then calculated area of body. Then I’ve divided mass value(object.mass of my “old” car - car that worked good) with area of body in order to get value of density. Not the best solution but solved my current problem.

But stil, I have to do a lot of work on learnig box2d and physics.