简体   繁体   中英

libgdx bind multiple part textures and stuff

I am developing an off road game, and I am new to libgdx.

I made a car, with only 3 parts: chassis, rear & front wheel. I got a "Zoomable" camera bind with chassis, chassis connected to wheels with Wheel Joint.

Chassis works fine with texture but not wheels.

Here's the problems:

  1. I can't figure out how to calculate the √(correct) vector2 of wheels to put it in the [Sprite.setPosition] method
  2. How to make my car faster cause it never >94

Focus.java

public class Focus extends InputAdapter {
    private Body chassis, rearWheel, frontWheel;
    private WheelJoint leftAxis, rightAxis;
    private float speed = 90f;
    private Sprite spriteChassis, spriteRearWheel, spriteFrontWheel;
    private float xOffSet = 5f;
    private float yOffSet = -2f;
    private float rwOffSet = 0;
    private float fwOffSet = 0;

    private float rwOffSetY = 0;
    private float fwOffSetY = 0;


    public float getOffSetX(){ return xOffSet; }
    public float getOffSetY(){ return yOffSet; }

    public Focus(World world, FixtureDef chassisFixtureDef, FixtureDef wheelFixtureDef, float x, float y) {
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyDef.BodyType.DynamicBody;
        bodyDef.position.set(x,y);
        bodyDef.gravityScale = 1;
        float width = 5.333f;
        float height = 1.933f;


        BodyEditorLoader loader = new BodyEditorLoader(Gdx.files.internal("data/focus.json"));
        chassis = world.createBody(bodyDef);
        loader.attachFixture(chassis, "focus", chassisFixtureDef, width);
        String imgpath = loader.getImagePath("focus");
        chassis.createFixture(chassisFixtureDef);
        chassis.setGravityScale(1.2f);

        spriteChassis = new Sprite(new Texture(imgpath));
        spriteRearWheel = new Sprite(new Texture("tires.png"));
        spriteFrontWheel = new Sprite(new Texture("tires.png"));

        // Wheels
        CircleShape wheelShape = new CircleShape();
        wheelShape.setRadius(height / 6f);

        wheelFixtureDef.shape = wheelShape;

        rearWheel = world.createBody(bodyDef);
        rearWheel.createFixture(wheelFixtureDef);

        frontWheel = world.createBody(bodyDef);
        frontWheel.createFixture(wheelFixtureDef);


        // Axels
        WheelJointDef axisDef = new WheelJointDef();
        axisDef.bodyA = chassis;
        axisDef.bodyB = rearWheel;
        rwOffSet = wheelShape.getRadius()*3.3f;
        axisDef.localAnchorA.x = rwOffSet;
        rwOffSetY = height/10.5f;
        axisDef.localAnchorA.y = rwOffSetY;
        axisDef.frequencyHz = chassisFixtureDef.density;
        axisDef.localAxisA.set(Vector2.Y);
        axisDef.maxMotorTorque = chassisFixtureDef.density * 24.5f;

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

//        right
//        Axels
        WheelJointDef axisDef2 = new WheelJointDef();
        axisDef2.bodyA = chassis;
        axisDef2.bodyB = frontWheel;
        axisDef2.localAnchorA.set(width, 0);
        axisDef2.frequencyHz = chassisFixtureDef.density;
        axisDef2.localAxisA.set(Vector2.Y);
        fwOffSet = width-wheelShape.getRadius()*3.f;
        axisDef2.localAnchorA.x = fwOffSet;
        fwOffSetY = height/9f;
        axisDef.localAnchorA.y = fwOffSetY;
        axisDef2.maxMotorTorque = chassisFixtureDef.density * 24.5f;
        rightAxis = (WheelJoint) world.createJoint(axisDef2);

    }



    @Override
    public boolean keyDown(int keycode) {

        switch(keycode) {
            case Input.Keys.W:
                leftAxis.enableMotor(false);
                rightAxis.enableMotor(true);
                rightAxis.setMotorSpeed(-speed);
                break;
            case Input.Keys.S:
                leftAxis.enableMotor(false);

                rightAxis.enableMotor(true);
                rightAxis.setMotorSpeed(speed);
                break;
            case Input.Keys.SPACE:
                leftAxis.enableMotor(true);
                leftAxis.setMotorSpeed(0);

                rightAxis.enableMotor(true);
                rightAxis.setMotorSpeed(0);
                break;
        }
        return true;
    }

    @Override
    public boolean keyUp(int keycode) {
        switch(keycode) {

            case Input.Keys.SPACE:
            case Input.Keys.W:
            case Input.Keys.S:
                leftAxis.enableMotor(false);
                rightAxis.enableMotor(false);
                break;
        }
        return true;
    }

    public Sprite getSpriteChassis(){ return spriteChassis; }

    public Sprite getSpriteRearWheel() { return spriteRearWheel; }

    public Sprite getSpriteFrontWheel() { return spriteFrontWheel; }

    public Body getChassis() { return chassis; }

    public Body getFrontWheel() { return frontWheel; }

    public Body getRearWheel() { return rearWheel; }
}

SmallHill.java (Screen)

public class SmallHill implements Screen {


    private final float PIXELS_PER_METER = 15f;     // how many pixels to a meter
    private final float TIME_STEP = 1 / 60f;        // 60 fps
    private final float SPEED = 1 / 60f;            // speed constant
    private final float MIN_ZOOM = .25f;            // How far in should we be able to zoom
    private final float ANGULAR_MOMENTUM = .5f;
    private final int VELOCITY_ITERATIONS = 8;      // copied from box2d example
    private final int POSITION_ITERATIONS = 3;      // copied from box2d example

    private World world;
    private Box2DDebugRenderer debugRenderer;
    private OrthographicCamera camera;
    private Body ball;
    private Focus focus;


    private BitmapFont font;

    private SpriteBatch batch;      
    private Texture texture;


    @Override
    public void show() {
        batch = new SpriteBatch();
        font = new BitmapFont();
        font.setColor(Color.RED);


        world = new World(new Vector2(0, -9.81f), true);
        debugRenderer = new Box2DDebugRenderer();

        camera = new OrthographicCamera();
        camera.zoom = 1f;

        BodyDef bodyDef = new BodyDef();

        // Shape
        ChainShape groundShape = new ChainShape();
        groundShape.createChain(new Vector2[] {new Vector2(-1,24),new Vector2(0,14),new Vector2(25,14),new Vector2(50,10),new Vector2(100,5),new Vector2(150,12),new Vector2(155,10), new Vector2(200,22),new Vector2(225,22),new Vector2(226,22.15f),new Vector2(227,22),new Vector2(229,22.25f),new Vector2(350,22),new Vector2(385,24),new Vector2(389,25),new Vector2(390,24),new Vector2(395,25),new Vector2(398,24),new Vector2(400,25),new Vector2(401,48) });
        CircleShape ballShape = new CircleShape();
        ballShape.setRadius(1f);
        ballShape.setPosition(new Vector2(-10, 16));

        // Fixture

        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = groundShape;
        fixtureDef.friction = .8f;
        fixtureDef.restitution = 0;
        world.createBody(bodyDef).createFixture(fixtureDef);

        fixtureDef.shape = ballShape;
        fixtureDef.friction = 0.9f;
        fixtureDef.restitution = .3f;
        fixtureDef.density = 3;
        bodyDef.type = BodyType.DynamicBody;

        fixtureDef.density = 5;
        fixtureDef.friction = .4f;
        fixtureDef.restitution = .1f;

        FixtureDef wheelFixtureDef = new FixtureDef();
        wheelFixtureDef.density = fixtureDef.density ;
        wheelFixtureDef.friction = 2;
        wheelFixtureDef.restitution = .7f;

        focus = new Focus(world, fixtureDef, wheelFixtureDef, 50, 14);

        wheelFixtureDef.shape.dispose();
        fixtureDef.shape.dispose();


        Gdx.input.setInputProcessor(new InputMultiplexer(new InputController() {
            @Override
            public boolean keyDown(int keycode) {
                switch(keycode) {
                    case Input.Keys.ESCAPE:
                        dispose();
                        break;
                    case Input.Keys.R:
                        camera.zoom = 1;
                        break;
                    case Input.Keys.PLUS:
                        camera.zoom = 10;
                        break;
                    case Input.Keys.MINUS:
                        camera.zoom = 1;
                        break;
                }
                return false;
            }



            @Override
            public boolean scrolled(int amount) {
                if(amount == -1 && camera.zoom <= MIN_ZOOM) {
                    camera.zoom = MIN_ZOOM;
                } else {
                    camera.zoom += amount / PIXELS_PER_METER;
                }
                return false;
            }
        },focus));
    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        world.step(TIME_STEP, VELOCITY_ITERATIONS, POSITION_ITERATIONS);
        camera.position.set(focus.getChassis().getWorldCenter().x,focus.getChassis().getWorldCenter().y,0);

        camera.update();

        String x;
        WheelJoint wj = (WheelJoint) focus.getChassis().getJointList().get(0).joint;
        x = (int)Math.abs(wj.getJointSpeed())+"";

        batch.begin();
        font.draw(batch, x, 20, 20);

        focus.getSpriteChassis().setPosition((Gdx.graphics.getWidth() / 2 - focus.getSpriteChassis().getWidth() / 2) + focus.getOffSetX(), (Gdx.graphics.getHeight() / 2 - focus.getSpriteChassis().getHeight() / 2) + focus.getOffSetY());


        focus.getSpriteChassis().setRotation(focus.getChassis().getAngle() * MathUtils.radiansToDegrees);
        focus.getSpriteChassis().setScale(1/camera.zoom);
        focus.getSpriteChassis().draw(batch);

        focus.getSpriteRearWheel().setPosition((Gdx.graphics.getWidth() / 2 - focus.getSpriteChassis().getWidth() / 2) , (Gdx.graphics.getHeight() / 2 - focus.getSpriteChassis().getHeight() / 2) );
        focus.getSpriteFrontWheel().setPosition((Gdx.graphics.getWidth() / 2 - focus.getSpriteChassis().getWidth() / 2) , (Gdx.graphics.getHeight() / 2 - focus.getSpriteChassis().getHeight() / 2) );
        //focus.getSpriteRearWheel().setPosition((Gdx.graphics.getWidth() / 2 - focus.getSpriteChassis().getWidth() / 2) + focus.getRwOffSet()*PIXELS_PER_METER*(1/camera.zoom), (Gdx.graphics.getHeight() / 2 - focus.getSpriteChassis().getHeight() / 2) + focus.getRwOffSetY()*PIXELS_PER_METER*(1/camera.zoom) );
        //focus.getSpriteFrontWheel().setPosition((Gdx.graphics.getWidth() / 2 - focus.getSpriteChassis().getWidth() / 2)+ focus.getFwOffSet()*PIXELS_PER_METER*(1/camera.zoom) , (Gdx.graphics.getHeight() / 2 - focus.getSpriteChassis().getHeight() / 2) + focus.getFwOffSetY()*PIXELS_PER_METER*(1/camera.zoom));

        focus.getSpriteRearWheel().setRotation(focus.getRearWheel().getAngle() * MathUtils.radiansToDegrees);
        focus.getSpriteFrontWheel().setRotation(focus.getFrontWheel().getAngle() * MathUtils.radiansToDegrees);
        focus.getSpriteRearWheel().setScale(1 / camera.zoom);
        focus.getSpriteRearWheel().draw(batch);
        focus.getSpriteFrontWheel().setScale(1 / camera.zoom);
        focus.getSpriteFrontWheel().draw(batch);

        batch.end();

        debugRenderer.render(world,  camera.combined);

    }

    @Override
    public void resize(int width, int height) {
        camera.viewportWidth = width / PIXELS_PER_METER;
        camera.viewportHeight = height / PIXELS_PER_METER;
    }

    @Override
    public void hide() { dispose(); }

    @Override
    public void pause() { }

    @Override
    public void resume() { }

    @Override
    public void dispose() {
        world.dispose();
        debugRenderer.dispose();
        batch.dispose();
        font.dispose();
    }
}

Can anyone help me understand? many thanks !!!

Box2D has a speed limit, which is about 2.0 units/timestep.
So if you step 60 times / second, you can move 2 * 60 = 120 units/second.
To increase the maximum speed you can decrease the timestep ie increase the number of steps/second.
If you, for example, increase it to 30, you can move up to 2 * 120 = 240 units/second.

Also make sure, that you are using meters as your unit. Box2D has been created with kg, meters and seconds in mind, so you should also use those units.

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