LibGDX Box2D Body and Sprite AND DebugRenderer out of sync
- by Free Lancer
I am having a couple issues with Box2D bodies. I have a GameObject holding a Sprite and Body. I use a ShapeRenderer to draw an outline of the Body's and Sprite's bounding boxes. I also added a Box2DDebugRenderer to make sure everything's lining up properly.
My problem is the Sprite and Body at first overlap perfectly, but as I turn the Body moves a bit off the sprite then comes back when the Car is facing either North or South.
Here's an image of what I mean: (Not sure what that line is, first time to show up)
BLUE is the Body, RED is the Sprite, PURPLE is the Box2DDebugRenderer.
Also, you probably noticed a purple square in the top right corner. Well that's the Car drawn by the Box2D Debug Renderer. I thought it might be the camera but I've been playing with the Cameras for hours and nothing seems to work. All give me weird results.
Here's my code:
Screen:
public void show() {
// --------------------- SETUP ALL THE CAMERA STUFF ------------------------------ //
battleStage = new Stage( 720, 480, false );
// Setup the camera. In Box2D we operate on a meter scale, pixels won't do it. So we use
// an Orthographic camera with a Viewport of 24 meters in width and 16 meters in height.
battleStage.setCamera( new OrthographicCamera( CAM_METER_WIDTH, CAM_METER_HEIGHT ) );
battleStage.getCamera().position.set( CAM_METER_WIDTH / 2, CAM_METER_HEIGHT / 2, 0 );
// The Box2D Debug Renderer will handle rendering all physics objects for debugging
debugger = new Box2DDebugRenderer( true, true, true, true );
//debugCam = new OrthographicCamera( CAM_METER_WIDTH, CAM_METER_HEIGHT );
}
public void render(float delta) {
// Update the Physics World, use 1/45 for something around 45 Frames/Second for mobile devices
physicsWorld.step( 1/45.0f, 8, 3 ); // 1/45 for devices
// Set the Camera matrices and clear the screen
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
battleStage.getCamera().update();
// Draw game objects here
battleStage.act(delta);
battleStage.draw();
// Again update the Camera matrices and call the debug renderer
debugCam.update();
debugger.render( physicsWorld, debugCam.combined);
// Vehicle handles its own interaction with the HUD
// update all Actors movements in the game Stage
hudStage.act( delta );
// Draw each Actor onto the Scene at their new positions
hudStage.draw();
}
Car: (extends Actor)
public Car( Texture texture, float posX, float posY, World world ) {
super( "Car" );
mSprite = new Sprite( texture );
mSprite.setSize( WIDTH * Consts.PIXEL_METER_RATIO, HEIGHT * Consts.PIXEL_METER_RATIO );
mSprite.setOrigin( mSprite.getWidth()/2, mSprite.getHeight()/2); // set the origin to be at the center of the body
mSprite.setPosition( posX * Consts.PIXEL_METER_RATIO, posY * Consts.PIXEL_METER_RATIO ); // place the car in the center of the game map
FixtureDef carFixtureDef = new FixtureDef();
mBody = Physics.createBoxBody( BodyType.DynamicBody, carFixtureDef, mSprite );
}
public void draw() {
mSprite.setPosition( mBody.getPosition().x * Consts.PIXEL_METER_RATIO, mBody.getPosition().y * Consts.PIXEL_METER_RATIO );
mSprite.setRotation( MathUtils.radiansToDegrees * mBody.getAngle() );
// draw the sprite
mSprite.draw( batch );
}
Physics: (Create the Body)
public static Body createBoxBody( final BodyType pBodyType, final FixtureDef pFixtureDef, Sprite pSprite ) {
float pRotation = 0;
float pWidth = pSprite.getWidth();
float pHeight = pSprite.getHeight();
final BodyDef boxBodyDef = new BodyDef();
boxBodyDef.type = pBodyType;
boxBodyDef.position.x = pSprite.getX() / Consts.PIXEL_METER_RATIO;
boxBodyDef.position.y = pSprite.getY() / Consts.PIXEL_METER_RATIO;
// Temporary Box shape of the Body
final PolygonShape boxPoly = new PolygonShape();
final float halfWidth = pWidth * 0.5f / Consts.PIXEL_METER_RATIO;
final float halfHeight = pHeight * 0.5f / Consts.PIXEL_METER_RATIO;
boxPoly.setAsBox( halfWidth, halfHeight ); // set the anchor point to be the center of the sprite
pFixtureDef.shape = boxPoly;
final Body boxBody = BattleScreen.getPhysicsWorld().createBody(boxBodyDef);
boxBody.createFixture(pFixtureDef);
}
Sorry for all the code and long description but it's hard to pin down what exactly might be causing the problem.