So I'm trying to implement collision detection in my game and I have a layer in the tmx file called Collision. The LIBGDX onsite tutorials doesnt cover interaction with object layers and it was hard to figure out how to render the map in the first place. This is how I render my screen, I would like to learn how to get my collision layer and then get my sprite to interact with it.

@Override
    public void render(float delta) {
        translateCamera();

        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

        camera.update();

        renderer.setView(camera);

        renderer.render(bgLayers);
        // renderer.render();

        batch.begin();

        batch.draw(playerDirect, Gdx.graphics.getWidth() / 2,
                Gdx.graphics.getHeight() / 2);

        batch.end();
        renderer.render(fgLayers);

    }
有帮助吗?

解决方案 2

I'd reccomend adding blocked properties to the actual tiles themselves - you can add tile properties via the Tiled editor on the actual tileset. You can retrieve their properties on the tileset. I'm going to quote the documentation:

A TiledMap contains one or more TiledMapTileSet instances. A tile set contains a number of TiledMapTile instances. There are multiple implementations of tiles, e.g. static tiles, animated tiles etc. You can also create your own implementation for special

Cells in a tile layer reference these tiles. Cells within a layer can reference tiles of multiple tile sets. It is however recommended to stick to a single tile set per layer to reduce texture switches.

Specifically, call getProperties on the tile in a tileset. This will retrieve the propeties - then you can compare to your custom attribute and this can tell you if a particular tile is blocked - then you can go ahead and implement your own collision logic.

其他提示

There is a way to use the object layer. Don't give up hope!

One major advantage of this method over using tile properties is the ease with which you can generate fewer, larger bodies for improved efficiency in Box2d. Plus, even better, those bodies can be any shape you want! Rather than dozens of squared-off bodies, my sample level in my game now has just three funny-shaped (read more organic-looking) ChainShape-based bodies.

I answered the same question on GameDev the other day, after a serious hunt deep in the jungles of the Web. The tutorial I found didn't quite work for me as-is, so a little editing later I came up with this:

public class MapBodyBuilder {

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

    public static Array<Body> buildShapes(Map map, float pixels, World world) {
        ppt = pixels;
        MapObjects objects = map.getLayers().get("Obstacles").getObjects();

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

        for(MapObject object : objects) {

            if (object instanceof TextureMapObject) {
                continue;
            }

            Shape shape;

            if (object instanceof RectangleMapObject) {
                shape = getRectangle((RectangleMapObject)object);
            }
            else if (object instanceof PolygonMapObject) {
                shape = getPolygon((PolygonMapObject)object);
            }
            else if (object instanceof PolylineMapObject) {
                shape = getPolyline((PolylineMapObject)object);
            }
            else if (object instanceof CircleMapObject) {
                shape = getCircle((CircleMapObject)object);
            }
            else {
                continue;
            }

            BodyDef bd = new BodyDef();
            bd.type = BodyType.StaticBody;
            Body body = world.createBody(bd);
            body.createFixture(shape, 1);

            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(CircleMapObject circleObject) {
        Circle circle = circleObject.getCircle();
        CircleShape circleShape = new CircleShape();
        circleShape.setRadius(circle.radius / ppt);
        circleShape.setPosition(new Vector2(circle.x / ppt, circle.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) {
            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;
    }
}

Assuming you've set things up so that the size of your tiles correspond to 1 square metre (1 square unit, if you prefer) in your Box2d World, the static Bodys this produces will be exactly where you drew them in Tiled. It was so satisfying to see this up and running, believe you me.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top