简体   繁体   中英

libGdx with Box2D loader bicycle wheel joint

I'm using libGdx framework with Box2D physics editor. I can't figure out what is wrong. Why i can't joint correctly wheels to chassis. Wheels not holding chassis. Sorry for mistake. Here pic. what i get:

 <img src='http://s4.postimg.org/a0d6ujpjt/test.jpg' border='0' alt="test" /> 

Code for my application:

package com.ernestyno.test;

import com.ernestyno.text.bodyeditorloader.BodyEditorLoader;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.physics.box2d.joints.WheelJoint;
import com.badlogic.gdx.physics.box2d.joints.WheelJointDef;

public class Dviratis extends InputAdapter {
private World world;
private float x, y, width;

private Body dviracioRemasBody, kairysRatasBody, desinysRatasBody;
private WheelJoint kairysRatasJoint, desinysRatasJoint;
private Vector2 dviracioRemasOrigin, ratasOrigin;
private Sprite remasSprite, kairysRatasSprite, desinysRatasSprite;
private Texture remasTexture, ratasTexture;

//FIXTURES
private FixtureDef dviracioRemasFixture, dviracioRatoFixture;

private float
//REMAS FIXTURE DUOMENYS
REMAS_DENSITY       = 5f,
REMAS_FRICTION      = .4f,
REMAS_RESTITUTION   = .3f,

//RATU FIXTURE DUOMENYS
RATAS_DENSITY       = REMAS_DENSITY * 1.5f,
RATAS_FRICTION      = 50f,
RATAS_RESTITUTION   = .4f;

private String 
BODY_EDITOR_FILE        = "json/dviratis.json",
BODY_EDITOR_REMAS_NAME  = "DviracioRemas",
BODY_EDITOR_RATAS_NAME  = "ratas";

public Dviratis(World world, float x, float y, float width) {
    this.world = world;
    this.x = x;
    this.y = y;
    this.width = width;

    this.setFixture();
    this.setSprite();
    this.setBody();
}

public void setFixture() {
    this.dviracioRemasFixture               = new FixtureDef();
    this.dviracioRatoFixture                = new FixtureDef();

    this.dviracioRemasFixture.density       = this.REMAS_DENSITY;
    this.dviracioRemasFixture.friction      = this.REMAS_FRICTION;
    this.dviracioRemasFixture.restitution   = this.REMAS_RESTITUTION;

    this.dviracioRatoFixture.density        = this.RATAS_DENSITY;
    this.dviracioRatoFixture.friction       = this.RATAS_FRICTION;
    this.dviracioRatoFixture.restitution    = this.RATAS_RESTITUTION;
}

public void setSprite() {
    this.remasTexture = new Texture(Gdx.files.internal("json/dviracio_remas.png"));
    this.remasTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
    this.remasSprite = new Sprite(this.remasTexture);
    this.remasSprite.setSize(this.width, this.width * this.remasSprite.getHeight() / this.remasSprite.getWidth());

    this.ratasTexture = new Texture(Gdx.files.internal("json/dviracio_ratas.png"));
    this.ratasTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
    this.desinysRatasSprite = new Sprite(this.ratasTexture);
    this.desinysRatasSprite.setSize(this.width / 3, this.width / 3);

    this.kairysRatasSprite = new Sprite(this.ratasTexture);
    this.kairysRatasSprite.setSize(this.width / 3, this.width / 3);
}

public void setBody() {
    BodyDef bodyDef = new BodyDef();
    BodyEditorLoader loader = new BodyEditorLoader(Gdx.files.internal(this.BODY_EDITOR_FILE));

    bodyDef.type = BodyType.DynamicBody;
    bodyDef.position.set(this.x, this.y);

    this.dviracioRemasBody = this.world.createBody(bodyDef);
    loader.attachFixture(this.dviracioRemasBody, this.BODY_EDITOR_REMAS_NAME, this.dviracioRemasFixture, this.width);
    this.dviracioRemasOrigin = loader.getOrigin(this.BODY_EDITOR_REMAS_NAME, this.width).cpy();

    this.desinysRatasBody = this.world.createBody(bodyDef);
    loader.attachFixture(this.desinysRatasBody, this.BODY_EDITOR_RATAS_NAME, this.dviracioRatoFixture, this.width / 3);

    this.kairysRatasBody = this.world.createBody(bodyDef);
    loader.attachFixture(this.kairysRatasBody, this.BODY_EDITOR_RATAS_NAME, this.dviracioRatoFixture, this.width / 3);

    this.ratasOrigin = loader.getOrigin(this.BODY_EDITOR_RATAS_NAME, this.width).cpy();

    //masinos kairio rato susiejimas prie masinos kuno
    WheelJointDef axisDef = new WheelJointDef();
    axisDef.bodyA = this.dviracioRemasBody;
    axisDef.bodyB = this.desinysRatasBody;
    //nuo centro ratu susiejimo atittraukimas i x ir y pozicija
    axisDef.localAnchorA.set(0.73f, -0.45f);
    axisDef.localAnchorB.set(0f, 0f);
    axisDef.localAxisA.set(Vector2.Y); //Vector2.Y = new Vector2(0, 1); - ratu amortizacija y asije, o ne x asije

    this.desinysRatasJoint = (WheelJoint) world.createJoint(axisDef);

    axisDef.bodyB = this.kairysRatasBody;
    axisDef.localAnchorA.set(-1f, -0.45f);
    axisDef.frequencyHz = this.dviracioRemasFixture.density; //amortizatoriaus galia
    axisDef.maxMotorTorque = this.dviracioRemasFixture.density * 10; //variklio galia

    this.kairysRatasJoint = (WheelJoint) world.createJoint(axisDef);
}

public void render() {
    Vector2 pozicija = this.dviracioRemasBody.getPosition().sub(this.dviracioRemasOrigin);

    this.remasSprite.setPosition(pozicija.x, pozicija.y);
    this.remasSprite.setOrigin(this.dviracioRemasOrigin.x, this.dviracioRemasOrigin.y);
    this.remasSprite.setRotation(this.dviracioRemasBody.getAngle() * MathUtils.radiansToDegrees);

    pozicija = this.desinysRatasBody.getPosition().sub(this.ratasOrigin);

    this.desinysRatasSprite.setPosition(pozicija.x, pozicija.y);
    this.desinysRatasSprite.setOrigin(this.ratasOrigin.x, this.ratasOrigin.y);
    this.desinysRatasSprite.setRotation(this.desinysRatasBody.getAngle() * MathUtils.radiansToDegrees);

    pozicija = this.kairysRatasBody.getPosition().sub(this.ratasOrigin);

    this.kairysRatasSprite.setPosition(pozicija.x, pozicija.y);
    this.kairysRatasSprite.setOrigin(this.ratasOrigin.x, this.ratasOrigin.y);
    this.kairysRatasSprite.setRotation(this.kairysRatasBody.getAngle() * MathUtils.radiansToDegrees);
}

public void draw(SpriteBatch batch) {
    this.remasSprite.draw(batch);
    this.desinysRatasSprite.draw(batch);
    this.kairysRatasSprite.draw(batch);
}

public Body getRemas() {
    return dviracioRemasBody;
}

public Body getDviracioRemasBody() {
    return dviracioRemasBody;
}
}

Huh... I found what is wrong. Program "physics-body-editor" generate's wrong circle center position in the .json file. The coordinates are cx and cy. So I replaced the BodyEditorLoader.java file. Created another attachFixture() method which allows you to describe another circle coordinates.

Instead of for circles:

loader.attachFixture(this.desinysRatasBody, this.BODY_EDITOR_RATAS_NAME, this.dviracioRatoFixture, this.width / 3);

Use:

loader.attachFixture(this.desinysRatasBody, this.BODY_EDITOR_RATAS_NAME, this.dviracioRatoFixture, this.width / 3, new Vector2(0,0));

If you want you can download BodyEditorLoader file

Now my wheels is at correct position. Result image

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM