Box2D用LIBGDX将车轮放在正确的位置

时间:2013-12-31 16:53:31

标签: java libgdx box2d physics

我正在开发一款自行车游戏,我在自行车上工作。 自行车底盘使用物理主体编辑器工具制作。 创建机箱

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);

    }

Motor类的构造函数

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 我试图改变axisDef.localAnchorA,但我仍然不能这样做。

我想要这样的东西 i want 任何人都可以帮助我吗?

2 个答案:

答案 0 :(得分:3)

我看到你手动为axisDef定义localAnchorA而不是localAnchorB。也许Java版本中没有一个,但是在box2d的c ++版本中。我猜测存在并且没有定义...这意味着它是(0,0)并且您将关节末端映射到身体的局部空间中的不同位置。

在联合def类/结构中,(通常)有一个Initialize(...)函数,你通常提供类似(bodyA,bodyB,anchorPointOnAInWorldSpace)的东西:

我通常在c ++(see this post)中这样做。我将c ++代码映射到Java上...我不是本机Java用户,所以可能会有一些东西......我相信这个想法是可靠的。

编辑有人已将我的c ++重新映射到Java。有一天,我可能要学习......享受。

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);

锚点通常类似于bodyA.GetWorldCenter()+偏移或固定点或bodyA上的其他点的位置。这也需要将锚位置映射到两个物体的局部空间中,以使它们重合。否则,你很容易忘记正确地做到这一点。

如果你想手动完成,我认为它会是这样的:

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);

在RevoluteJointDef的Java版本中是否存在Initialize(...)方法......如果确实如此,它会让生活更轻松。

这有用吗?

答案 1 :(得分:0)

这肯定是LocalAnchor A和B位置错误,在LocalAnchorA上手动使用(0,0)值并且每次测试都将其更改为适当的值。

我应该说两个轮子的LocalAnchorB应该是(0,0)。并考虑在游戏中使用比例,如果您使用的是比例,则将比例乘以LocalAnchors。