2

I am developing a bike game, and i am working at my bike. The bike chassis is made using the Physics Body Editor tool. Creating the chassis

void createChasis(World world, Sprite sprite) {

        BodyEditorLoader loader = new BodyEditorLoader(
                Gdx.files.internal("data/motor/bike"));
        BodyDef bd = new BodyDef();
        bd.position.set(0, 4);

        bd.type = BodyType.DynamicBody;
        FixtureDef fd = new FixtureDef();
        fd.density = 0.2f;
        fd.friction = 0.1f;
        fd.restitution = 0.4f;

        chassis = world.createBody(bd);
        loader.attachFixture(chassis, "motor", fd, 2);
        chassis.setUserData(sprite);

    }

And the constructor of the Motor class

public Motor2D(World world) {
    float width = 2;
    float height = 1;
    FixtureDef chassisFixtureDef = new FixtureDef();
    chassisFixtureDef.density = 1;
    chassisFixtureDef.friction = 1;
    chassisFixtureDef.restitution = 0.1f;

    FixtureDef wheelFixtureDef = new FixtureDef();
    wheelFixtureDef.density = 0.6f;
    wheelFixtureDef.restitution = 0.1f;
    wheelFixtureDef.friction = 2f;

    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyType.DynamicBody;
    bodyDef.position.set(0, 5);

    // chassis
    Sprite roata, cadru;
    Texture textura = new Texture(Gdx.files.internal("data/texture.PNG"));
    cadru = new Sprite(new TextureRegion(textura, 0, 0, 500, 264));
    roata = new Sprite(new TextureRegion(textura, 0, 254, 178, 178));
    cadru.setOrigin(cadru.getWidth() / 2, cadru.getHeight() / 2);
    roata.setOrigin(roata.getWidth() / 2, roata.getHeight() / 2);
    createChasis(world, cadru);

    // left wheel
    CircleShape wheelShape = new CircleShape();
    wheelShape.setRadius(height / 3.5f);
    // wheelShape.setPosition(new Vector2(1, 1));
    wheelFixtureDef.shape = wheelShape;

    leftWheel = world.createBody(bodyDef);

    leftWheel.createFixture(wheelFixtureDef);
    leftWheel.setUserData(roata);

    // right wheel
    // wheelShape.setPosition(new Vector2(2, 1));
    rightWheel = world.createBody(bodyDef);
    rightWheel.createFixture(wheelFixtureDef);
    rightWheel.setUserData(roata);
    // left axis
    // create axes

    WheelJointDef axisDef = new WheelJointDef();

    axisDef.bodyA = chassis;

    axisDef.localAnchorA.set(-width  , -height / 2);

    axisDef.bodyB = leftWheel;

    axisDef.localAxisA.set(Vector2.Y);

    axisDef.frequencyHz = 1.75f;

    axisDef.motorSpeed = motorSpeed;

    leftAxis = (WheelJoint) world.createJoint(axisDef);

    axisDef.bodyB = rightWheel;

    axisDef.localAnchorA.x *= -1;

    rightAxis = (WheelJoint) world.createJoint(axisDef);

}

My output I tried to change axisDef.localAnchorA but i still can't do this.

I want something like this i want Can anyone help me?

Boldijar Paul
  • 5,405
  • 9
  • 46
  • 94
  • The code seems ok, it looks like maybe the distance between the wheels is just wrong. Where do the values 2 and 1 from for the width and height come from? – iforce2d Dec 31 '13 at 20:37

2 Answers2

3

I see you are manually defining localAnchorA for axisDef but not localAnchorB. Perhaps there isn't one in the Java version, but there is in the c++ version of box2d. I'm guessing there is and it is not defined...which would mean it is (0,0) and you have the joint ends mapped to different positions in the local spaces of the bodies.

On the joint def class/structure, there is (usually) an Initialize(...) function which you usually feed something like (bodyA, bodyB, anchorPointOnAInWorldSpace):

I usually do this in c++ (see this post). I mapped the c++ code onto Java for you...I'm not a native Java user, so there may be something off...the idea is solid, I believe.

EDIT Someone has kindly remapped my c++ to Java. Some day, I may have to learn...enjoy.

RevoluteJointDef jointDef = new RevoluteJointDef();
Vector2 anchor = (new Vector2(-width,-height/2)).add(chassis.getWorldCenter());
jointDef.initialize(chassis, wheel, anchor);
jointDef.collideConnected = true;
world.createJoint(jointDef);

The anchor point is usually something like bodyA.GetWorldCenter()+offset or the position of a fixture or some other point on bodyA. This also takes care of mapping the anchor positions into the local space of both bodies so that they coincide. Otherwise, you can easily forget to do it correctly.

If you want to do it manually, I would think it would be something like:

RevoluteJointDef jointDef = new RevoluteJointDef();
Vector2 anchor = (new Vector2(-width,-height/2)).add(chassis.getWorldCenter());
jointDef.bodyA = chassis;
jointDef.bodyB = wheel;
jointDef.localAnchorA = chassis.getLocalPoint(anchor);
jointDef.localAnchorB = wheel.getLocalPoint(anchor);
jointDef.referenceAngle = wheel.getAngle() - chassis.getAngle();
world.createJoint(jointDef);

Does the Initialize(...) method exist in the Java version of RevoluteJointDef...it would make life easier if it does.

Was this helpful?

Community
  • 1
  • 1
FuzzyBunnySlippers
  • 3,387
  • 2
  • 18
  • 28
0

This is certainly LocalAnchor A and B position is wrong, manually use (0,0) values on LocalAnchorA and with every test change it to appropriate values.

I should say that LocalAnchorB for both wheel should be (0,0). and consider Scale on your game, if you are using scale then multiply scale with LocalAnchors.

daniel
  • 697
  • 5
  • 15