This project is read-only.

Gravity Issue

Jan 20, 2010 at 5:10 PM

Im porting my box2d project from Java to c# (XNA). But i've got some problems with the gravity and other forces.

The bodies  are falling with a linear velocity (no acceleration), and I dont understand why.

I made a simple code just to test the effect of these forces.

 

I just created a new Windows Game Project in the "Visual C# 2008 Express Edition", then I imported the Box2D.XNA libraries and created the function createWorld().

I call the createWorld() inside the Initialize() function and call the world.Step() inside the Update() function.

And finaly, inside the Draw() function I draw a sprite (using the spriteBatch.Draw) passing the body.GetPosition() in the position parameter.

It's a simple approach and I dont understand why it doesn't work.

Please help me.

This is the link to the complete project:  http://rapidshare.com/files/338343452/WindowsGame9.rar.html

Here follows the main part of the code: 

protected override void Update(GameTime gameTime)
{
       world.Step(1/60, 8, 3);

       if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

base.Update(gameTime);
}

 

 protected void createWorld()
 {
     world = new World(new Vector2(0, 100), false);

     PolygonShape polygonShape = new PolygonShape();
     polygonShape.SetAsBox(10, 10);

     FixtureDef polygonDef = new FixtureDef();      
polygonDef.shape = polygonShape; polygonDef.density = 5; polygonDef.restitution = 0.5f; polygonDef.friction = 0.5f; polygonDef.isSensor = false; BodyDef bodyDef = new BodyDef(); bodyDef.position.X = 400; bodyDef.position.Y = 0; bodyDef.angle = 0; bodyDef.fixedRotation = false; bodyDef.type = BodyType.Dynamic; body = world.CreateBody(bodyDef); body.CreateFixture(polygonDef); body.SynchronizeFixtures(); body.SynchronizeTransform(); }

 

PS: It seems the top speed reached through acceleration in this manner is equivalent to twice the value 60, as i used in world.Step(1/60, 8, 3);

If I leave it as 60, for instance, the maximum speed is 120, if I change it to 80, the maximum speed becomes 160.

Jan 21, 2010 at 5:02 AM
Edited Jan 21, 2010 at 5:07 AM

There is a setting called Settings.b2_maxTranslation which defaults to 2.

This gets multiplied by the inverse time step (like you pointed out) to limit large velocities.

In this case 120m/s is considered a large velocity for an iterative solver to deal with.

Typically with an iterative physics engine like Box2D you will want to scale things down, I usually use a scale of 1/64 and a gravity of 30.

Depending on what you are trying to do the simplest thing might be to just bump the setting up higher.

Also remember to call world.ClearForces() after each step or else forces that you apply manually will build up between frames.

Jan 21, 2010 at 5:16 AM

Elaborating on this, keep in mind that you are treating 1 pixel as 1 meter if you don't scale things and sync your sprite directly to the physics body position.

So the car in your demo is rediculously huge and falling a very long ways so the engine clamps its velocity at 120m/s.  This is about 268mph so faster than an F1 race car could go at top speed.

Even if you want to simulate speeds that high, your car probably shouldn't be so massive :)

This is why I usually use a 1/64 scale that way a 64x64 pixel block represents 1x1 meter in the physics world which seems about right for most 2D games.

Jan 25, 2010 at 7:34 PM

Thank you for the hints!

We figured it had something to do with scale afterwards, but didn't
know about masTRanslation and the need to call ClearForces.

We really appreciate the time you took to analyse our code.  Thank you
once again for the help. :D

Best regards!