Libgdx Box2D在平铺地图对象图层的主体顶部错误的精灵位置

时间:2014-12-22 16:12:28

标签: java libgdx box2d sprite tiled

我正在尝试将精灵绘制到我从tilemap对象层创建的实体上 当我将sprite绘制到我从代码手动创建的实体上时,它可以正常工作。然而,当我尝试在我从tilemap创建的身体上绘制精灵时,它不会将精灵放到身体上。
它在世界上吸引它们,但在错误的地方,有点像投影矩阵没有设置或错误或其他东西。

我在stackexchange上发现了一个同样的问题他/她描述了同样的问题和代码示例。可悲的是,没有回复/解决方案。我有同样的问题,但我不使用每米转换像素。

stackoverflow上的第一篇帖子......温柔......:)

这是链接:
https://gamedev.stackexchange.com/questions/86474/box2d-shape-fixture-position-vs-body-position

让我提供一个screentshot以及我的问题:
http://i.imgur.com/o6WC8ks.png

代码:
游戏代码:

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
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.BodyType;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.Array;
import com.seve.carramps.entities.Car;
import com.seve.carramps.handlers.MapObjectLoad;

public class testLevel implements Screen {

    private World world;
    private Box2DDebugRenderer debugRenderer;
    private SpriteBatch batch;
    private OrthographicCamera camera;

    private final float TIMESTEP = 1 / 60f;
    private final int VELOCITYITERATIONS = 8, POSITIONITERATIONS = 3;

    private Array<Body> pigs;
    private Car car;
    static int userd = 0;
    TiledMap map;
    OrthogonalTiledMapRenderer renderer;


    // The pixels per tile. If your tiles are 16x16, this is set to 16f
    private static float ppt = 32f;

    private Sprite carSprite, wheelSprite, treeSprite;

    private Array<Body> tmpBodies = new Array<Body>();

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

        world.step(TIMESTEP, VELOCITYITERATIONS, POSITIONITERATIONS);

        camera.position.set(car.getChassis().getPosition().x, car.getChassis()
                .getPosition().y, 0);
        camera.update();

        batch.setProjectionMatrix(camera.combined);

        batch.begin();

        world.getBodies(tmpBodies);
        for (Body body : tmpBodies) {
            if (body.getUserData() != null
                    && body.getUserData() instanceof Sprite) {
                Sprite sprite = (Sprite) body.getUserData();
                sprite.setPosition(body.getPosition().x - sprite.getWidth() / 2,(body.getPosition().y - sprite.getHeight() / 2));
                sprite.setRotation(body.getAngle() * MathUtils.radiansToDegrees);
                sprite.draw(batch);
            }
        }

        batch.end();

        debugRenderer.render(world, camera.combined);
    }

    @Override
    public void show() {

        setupWorld();

        map = new TmxMapLoader().load("carground.tmx");
        renderer = new OrthogonalTiledMapRenderer(map);


        createCar();

        new MapObjectLoad(map, ppt, world, "ground", BodyType.StaticBody, null, null);
        new MapObjectLoad(map, ppt, world, "ramps", BodyType.DynamicBody, null, "ramp");
        new MapObjectLoad(map, ppt, world, "treeWalls", BodyType.DynamicBody, treeSprite, "treeWall");
        new MapObjectLoad(map, ppt, world, "enemies", BodyType.DynamicBody, null, "enemy");

        carSprite = new Sprite(new Texture("car.png"));
        carSprite.setSize(4, 2);
        carSprite
                .setOrigin(carSprite.getWidth() / 2, carSprite.getHeight() / 2);
        car.getChassis().setUserData(carSprite);

        wheelSprite = new Sprite(new Texture("wheel.png"));
        wheelSprite.setSize(0.9f, 0.9f);
        wheelSprite.setOrigin(wheelSprite.getWidth() / 2,
                wheelSprite.getHeight() / 2);
        car.getLeftWheel().setUserData(wheelSprite);
        car.getRightWheel().setUserData(wheelSprite);


        inputProcessor();

    }

    private void createCar() {
        // car
        FixtureDef fixtureDef = new FixtureDef(), wheelFixtureDef = new FixtureDef();

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

        wheelFixtureDef.density = fixtureDef.density * 1.5f;
        wheelFixtureDef.friction = 50;
        wheelFixtureDef.restitution = .4f;

        car = new Car(world, fixtureDef, wheelFixtureDef, -2.5f, 5, 3.8f, 1.7f);
    }

    private void setupWorld() {
        world = new World(new Vector2(0, -9.81f), true);
        debugRenderer = new Box2DDebugRenderer();
        batch = new SpriteBatch();
        camera = new OrthographicCamera();

    }

    private void inputProcessor() {
        Gdx.input.setInputProcessor(new InputMultiplexer(new InputAdapter() {
            @Override
            public boolean keyDown(int keycode) {
                switch (keycode) {
                case Keys.ESCAPE:
                    ((Game) Gdx.app.getApplicationListener())
                            .setScreen(new testLevel());
                    break;
                }
                return false;
            }

            @Override
            public boolean scrolled(int amount) {
                camera.zoom += amount / 25f;
                return true;
            }
        }, car));
    }

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

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

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }

    @Override
    public void dispose() {
        world.dispose();
        debugRenderer.dispose();
        carSprite.getTexture().dispose();
    }

}

获取来自不同对象层的实体的类:

import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.maps.Map;
import com.badlogic.gdx.maps.MapObject;
import com.badlogic.gdx.maps.MapObjects;
import com.badlogic.gdx.maps.objects.EllipseMapObject;
import com.badlogic.gdx.maps.objects.PolygonMapObject;
import com.badlogic.gdx.maps.objects.PolylineMapObject;
import com.badlogic.gdx.maps.objects.RectangleMapObject;
import com.badlogic.gdx.maps.objects.TextureMapObject;
import com.badlogic.gdx.math.Ellipse;
import com.badlogic.gdx.math.Rectangle;
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.ChainShape;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.Shape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.Array;

public class MapObjectLoad {

    // The pixels per tile. If your tiles are 16x16, this is set to 16f
    private static float ppt = 32f;

    public MapObjectLoad(Map map, float pixels, World world, String layer,
            BodyDef.BodyType bodytype, Sprite sprite, String userData) {

        buildShapes(map, pixels, world, layer, bodytype, sprite, userData);

    }

//  public MOL(Map map, float pixels, World world, String layer,
//          BodyDef.BodyType bodytype, String userData) {
//
//      buildShapes(map, pixels, world, layer, bodytype, null , userData);
//
//  }

    public Array<Body> buildShapes(Map map, float pixels, World world,
            String layer, BodyDef.BodyType bodytype, Sprite sprite, String userData) {

        ppt = pixels;
        Body body = null;

        MapObjects objects = map.getLayers().get(layer).getObjects();

        Array<Body> bodies = new Array<Body>();

        for (MapObject object : objects) {

            if (object instanceof TextureMapObject) {
                continue;
            }

            Shape shape;

            if (object instanceof RectangleMapObject) {
                // System.out.println("Rectangle found");
                shape = getRectangle((RectangleMapObject) object);
            } else if (object instanceof PolygonMapObject) {
                // System.out.println("Polygon found");
                shape = getPolygon((PolygonMapObject) object);
            } else if (object instanceof PolylineMapObject) {
                // System.out.println("Polyline found");
                shape = getPolyline((PolylineMapObject) object);
            } else if (object instanceof EllipseMapObject) {
                // System.out.println("Circle found");
                shape = getCircle((EllipseMapObject) object);
            } else {
                continue;
            }

            BodyDef bd = new BodyDef();
            bd.type = bodytype;
//          bd.position.set(0, 0);
            body = world.createBody(bd);
            body.createFixture(shape, 1).setUserData(userData);

//          sprite = new Sprite(new Texture("treeWall.png"));
//          sprite.setSize(.5f, 2);
//          sprite.setOrigin(sprite.getWidth() / 2, sprite.getHeight() / 2);
//          body.setUserData(sprite);

            bodies.add(body);

            shape.dispose();
        }
        return bodies;
    }

    private static PolygonShape getRectangle(RectangleMapObject rectangleObject) {
        Rectangle rectangle = rectangleObject.getRectangle();
        PolygonShape polygon = new PolygonShape();
        Vector2 size = new Vector2(
                (rectangle.x + rectangle.width * 0.5f) / ppt,
                (rectangle.y + rectangle.height * 0.5f) / ppt);
        polygon.setAsBox(rectangle.width * 0.5f / ppt, rectangle.height * 0.5f
                / ppt, size, 0.0f);

        return polygon;
    }

    private static CircleShape getCircle(EllipseMapObject object) {
        Ellipse ellipse = object.getEllipse();
        CircleShape circleShape = new CircleShape();
        circleShape.setRadius((ellipse.width / 2) / ppt);
        // circleShape.setPosition(new Vector2((ellipse.x + (ellipse.width / 2))
        // / ppt, (ellipse.y - (ellipse.height / 2)) / ppt));
        circleShape.setPosition(new Vector2((ellipse.x + (ellipse.width / 2))
                / ppt, ellipse.y / ppt));
        return circleShape;
    }

    private static PolygonShape getPolygon(PolygonMapObject polygonObject) {
        PolygonShape polygon = new PolygonShape();
        float[] vertices = polygonObject.getPolygon().getTransformedVertices();

        float[] worldVertices = new float[vertices.length];

        for (int i = 0; i < vertices.length; ++i) {
            // System.out.println(vertices[i]);
            worldVertices[i] = vertices[i] / ppt;
        }

        polygon.set(worldVertices);
        return polygon;
    }

    private static ChainShape getPolyline(PolylineMapObject polylineObject) {
        float[] vertices = polylineObject.getPolyline()
                .getTransformedVertices();
        Vector2[] worldVertices = new Vector2[vertices.length / 2];

        for (int i = 0; i < vertices.length / 2; ++i) {
            worldVertices[i] = new Vector2();
            worldVertices[i].x = vertices[i * 2] / ppt;
            worldVertices[i].y = vertices[i * 2 + 1] / ppt;
        }

        ChainShape chain = new ChainShape();
        chain.createChain(worldVertices);
        return chain;
    }

}

创建汽车的类:

import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputAdapter;
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.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
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 Car extends InputAdapter{

    private Body chassis, leftWheel, rightWheel;
    private WheelJoint leftAxis, rightAxis;
    public Body getLeftWheel() {
        return leftWheel;
    }

    public Body getRightWheel() {
        return rightWheel;
    }

    private float motorSpeed = 75;

    public Car(World world, FixtureDef chassisFixtureDef,
            FixtureDef wheelsFixtureDef, float x, float y, float width,
            float height) {
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyType.DynamicBody;
        bodyDef.position.set(x, y);

        // CHASSIS
        PolygonShape chassisShape = new PolygonShape();
        // chassisShape.set(new float[] {x1, y1, x2, y2}); //counterclockwise
        // order
        chassisShape.set(new float[] { -width / 2, -height / 2, width / 2,
                -height / 2, width / 2 * .4f, height / 2, -width / 2 * .8f,
                height / 2 * .8f });

        chassisFixtureDef.shape = chassisShape;

        chassis = world.createBody(bodyDef);
        chassis.createFixture(chassisFixtureDef).setUserData("car");;

        // LEFT WHEEL
        CircleShape wheelShape = new CircleShape();
        wheelShape.setRadius(height / 3.5f);

        wheelsFixtureDef.shape = wheelShape;

        leftWheel = world.createBody(bodyDef);
        leftWheel.createFixture(wheelsFixtureDef);

        // RIGHT WHEEL
        rightWheel = world.createBody(bodyDef);
        rightWheel.createFixture(wheelsFixtureDef);

        //left axis;
        WheelJointDef axisDef = new WheelJointDef();
        axisDef.bodyA = chassis;
        axisDef.bodyB = leftWheel;
        axisDef.localAnchorA.set(-width / 2 * 1f + wheelShape.getRadius(), -height / 2 * .7f);
        axisDef.frequencyHz = chassisFixtureDef.density; // = density af chassis (5) så den kan holde chassis
        axisDef.localAxisA.set(Vector2.Y);
//      axisDef.maxMotorTorque = 50;
        axisDef.maxMotorTorque = chassisFixtureDef.density * 50;
        leftAxis = (WheelJoint) world.createJoint(axisDef);

        //right axis
        axisDef.bodyB = rightWheel;
        axisDef.localAnchorA.set(width / 2 * .15f + wheelShape.getRadius(), -height / 2 * .8f);

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

    @Override
    public boolean keyDown(int keycode) {
        switch (keycode) {
        case Keys.W:
            System.out.println("test");
            leftAxis.enableMotor(true);
            leftAxis.setMotorSpeed(-motorSpeed);
            break;

        case Keys.S:
            leftAxis.enableMotor(true);
            leftAxis.setMotorSpeed(motorSpeed);

            break;

        }
        return true;
    }

    @Override
    public boolean keyUp(int keycode) {
        switch (keycode) {
        case Keys.W:
        case Keys.S:
            leftAxis.enableMotor(false);

            break;

        }
        return true;
    }

    public Body getChassis() {
        return chassis;
    }

}

0 个答案:

没有答案