Why does wheel movement in Box2d doesn't cause car to move?

423 Views Asked by At

I'm working on moving vehicle based on Box 2d physics for my Android game (Java + LibGDX). When I thought I have everything up and running my, my car with two wheels stands on the ground but when I rotate the wheels The car does not move.

Screenshot

That's my Game class:

public class MyGdxGame implements ApplicationListener {
World world = new World(new Vector2(0, -10), true);

Box2DDebugRenderer debugRenderer;
OrthographicCamera camera;

static final float BOX_STEP=1/60f;
static final int BOX_VELOCITY_ITERATIONS=6;
static final int BOX_POSITION_ITERATIONS=2;

static final int WIDTH=256;
static final int HEIGHT=169;

Hero hero;
MovableBox box;



@Override
public void create() {
    camera = new OrthographicCamera();
    camera.viewportHeight = HEIGHT;
    camera.viewportWidth = WIDTH;
    camera.position.set(camera.viewportWidth * .5f, camera.viewportHeight * .5f, 0f);
    camera.update();

   Vector2[] anArray;
   anArray = new Vector2[4];

    anArray[0]= new Vector2(-30,0);
    anArray[1]= new Vector2(55,55);
    anArray[2]= new Vector2(110,55);
    anArray[3]= new Vector2(195,0);

    //Ground body
    BodyDef groundBodyDef =new BodyDef();
    groundBodyDef.position.set(new Vector2(-8-13-20-20-10, -44));
    Body groundBody = world.createBody(groundBodyDef);
    PolygonShape groundBox = new PolygonShape();
    groundBox.set(anArray);
    //groundBox.setAsBox((camera.viewportWidth) * 2, 10.0f);
    groundBody.createFixture(groundBox, 0.0f);

    //Ground body
    BodyDef groundBodyDef2 =new BodyDef();

    groundBodyDef2.position.set(new Vector2(13*11-4-7-8-13-20-20-10, -44));
    Body groundBody2 = world.createBody(groundBodyDef2);
    PolygonShape groundBox2 = new PolygonShape();
    groundBox2.set(anArray);
    //groundBox.setAsBox((camera.viewportWidth) * 2, 10.0f);
    groundBody2.createFixture(groundBox2, 0.0f);

    hero = new Hero();
    hero.create(world, 0, 0);

    box.create(world, WIDTH / 4 * 3, HEIGHT / 2);
    boxes.add(box);

    debugRenderer = new Box2DDebugRenderer();
}
private void update(){
    hero.update();

    for(MovableBox b : boxes) {
        b.update();
    }
}
@Override
public void dispose() {
}
@Override
public void render() {
    update();
    camera.position.set(hero.getPos(), 0f);
    camera.update();
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    debugRenderer.render(world, camera.combined);
    world.step(BOX_STEP, BOX_VELOCITY_ITERATIONS, BOX_POSITION_ITERATIONS);
}
@Override
public void resize(int width, int height) {
}
@Override
public void pause() {
}
@Override
public void resume() {
}

And Hero class (which should be called a car actually)

    Body body;
Body wheel, wheel2;
public void create(World world, int posx, int posy){

    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyDef.BodyType.DynamicBody;
    bodyDef.position.set(posx, posy);
    body = world.createBody(bodyDef);
    PolygonShape dynamicCircle = new PolygonShape();
    dynamicCircle.setAsBox(8, 3);
    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = dynamicCircle;
    fixtureDef.density = 4.0f;
    fixtureDef.restitution = 0.1f;
    fixtureDef.friction=0.95f;
    body.createFixture(fixtureDef);

    BodyDef bodyDef2 = new BodyDef();
    bodyDef2.type = BodyDef.BodyType.DynamicBody;
    wheel = world.createBody(bodyDef2);
    CircleShape dynamicCircle2 = new CircleShape();
    dynamicCircle2.setRadius(2);
    FixtureDef fixtureDef2 = new FixtureDef();
    fixtureDef2.shape = dynamicCircle2;
    fixtureDef2.density = 4;
    fixtureDef2.friction=3.0f;
    fixtureDef2.restitution=0.1f;
    wheel.createFixture(fixtureDef2);

    wheel2 = world.createBody(bodyDef2);
    wheel2.createFixture(fixtureDef2);


    RevoluteJointDef revoluteJointDef  = new RevoluteJointDef();
    revoluteJointDef.bodyA = body;
    revoluteJointDef.bodyB = wheel;
    revoluteJointDef.localAnchorA.add(-8,-6);
    world.createJoint(revoluteJointDef);

    RevoluteJointDef revoluteJointDef2  = new RevoluteJointDef();
    revoluteJointDef2.bodyA = body;
    revoluteJointDef2.bodyB = wheel2;
    revoluteJointDef2.localAnchorA.add(8,-6);
    world.createJoint(revoluteJointDef2);

}
public Vector2 getPos(){
    return body.getPosition();
}
public void update(){
    if(Gdx.input.isTouched())
    {
        if(Gdx.input.getX()<600){
            wheel.setTransform(wheel.getPosition().x,wheel.getPosition().y,wheel.getAngle()+0.1f);
            wheel2.setTransform(wheel2.getPosition().x,wheel2.getPosition().y, wheel2. getAngle() + 0.1f);
        }
        else{
            wheel.setTransform(wheel.getPosition().x,wheel.getPosition().y,wheel.getAngle()-0.1f);
            wheel2.setTransform(wheel2.getPosition().x,wheel2.getPosition().y,wheel2.getAngle()-0.1f);

        }


    }
}
1

There are 1 best solutions below

0
On

Well I think there are two things you need to consider.

First of all I think if you want your physics engine to "force" the car to move on wheels spin, you probably should look into damping parameters of BodyDef (linearDamping and angularDamping). Setting those for ground and car wheels might help you move your car on wheels spin.

The second thing is that you really need to analyze if it's the proper approach. Maybe you should think about simulating movement of your car by moving the body of your car itself and spinning your wheels. I think this approach should give you more control on the car movement.