Skip to main content
deleted 51 characters in body
Source Link
driima
  • 995
  • 4
  • 23
public final class Physics {

    public static final float PIXELS_PER_UNIT = 32f;

    private Physics() {}

    // UNIT CALCULATION AND CONVERSION:

    public static float toUnits(float pixels) {
        return pixels / PIXELS_PER_UNIT;
    }

    public static Vector toUnits(Vector2 pixels) {
        return new Vector2(toUnits(pixels.x), toUnits(pixels.y));
    }

    public static float toPixels(float units) {
        return units * PIXELS_PER_UNIT;
    }

    public static Vector2 toPixels(Vector2 units) {
        return new Vector2(toPixels(units.x), toPixels(units.y));
    }
}
public final class Physics {

    public static final float PIXELS_PER_UNIT = 32f;

    private Physics() {}

    // UNIT CALCULATION AND CONVERSION:

    public static float toUnits(float pixels) {
        return pixels / PIXELS_PER_UNIT;
    }

    public static Vector toUnits(Vector2 pixels) {
        return new Vector2(toUnits(pixels.x), toUnits(pixels.y));
    }

    public static float toPixels(float units) {
        return units * PIXELS_PER_UNIT;
    }

    public static Vector2 toPixels(Vector2 units) {
        return new Vector2(toPixels(units.x), toPixels(units.y));
    }
}
public final class Physics {

    public static final float PIXELS_PER_UNIT = 32f;

    private Physics() {}

    public static float toUnits(float pixels) {
        return pixels / PIXELS_PER_UNIT;
    }

    public static Vector toUnits(Vector2 pixels) {
        return new Vector2(toUnits(pixels.x), toUnits(pixels.y));
    }

    public static float toPixels(float units) {
        return units * PIXELS_PER_UNIT;
    }

    public static Vector2 toPixels(Vector2 units) {
        return new Vector2(toPixels(units.x), toPixels(units.y));
    }
}
Source Link
driima
  • 995
  • 4
  • 23

I realise this is five months old, but still relevant. The way I do it is by creating a Physics utility class for my unit calculation and conversion:

public final class Physics {

    public static final float PIXELS_PER_UNIT = 32f;

    private Physics() {}

    // UNIT CALCULATION AND CONVERSION:

    public static float toUnits(float pixels) {
        return pixels / PIXELS_PER_UNIT;
    }

    public static Vector toUnits(Vector2 pixels) {
        return new Vector2(toUnits(pixels.x), toUnits(pixels.y));
    }

    public static float toPixels(float units) {
        return units * PIXELS_PER_UNIT;
    }

    public static Vector2 toPixels(Vector2 units) {
        return new Vector2(toPixels(units.x), toPixels(units.y));
    }
}

I then create a ShapeFactory class which converts MapObjects into shapes of the same type:

public final class ShapeFactory {

    private ShapeFactory() {}

    public static PolygonShape getRectangle(RectangleMapObject rectangleObject) {
        return getRectangle(rectangleObject.getRectangle());
    }

    public static PolygonShape getRectangle(Rectangle rectangle) {
        PolygonShape polygon = new PolygonShape();

        Vector2 size = new Vector2(
                Physics.toUnits(rectangle.x + rectangle.width * 0.5f),
                Physics.toUnits(rectangle.y + rectangle.height * 0.5f)
        );

        polygon.setAsBox(
                Physics.toUnits(rectangle.width * 0.5f),
                Physics.toUnits(rectangle.height * 0.5f),
                size,
                0.0f
        );

        return polygon;
    }

    public static CircleShape getCircle(CircleMapObject circleObject) {
        return getCircle(circleObject.getCircle());
    }

    public static CircleShape getCircle(Circle circle) {
        CircleShape circleShape = new CircleShape();
        circleShape.setRadius(Physics.toUnits(circle.radius));
        circleShape.setPosition(new Vector2(Physics.toUnits(circle.x), Physics.toUnits(circle.y)));

        return circleShape;
    }

    public static PolygonShape getPolygon(PolygonMapObject polygonObject) {
        return getPolygon(polygonObject.getPolygon());
    }

    public static PolygonShape getPolygon(Polygon polygon) {
        PolygonShape polygonShape = new PolygonShape();

        float[] vertices = polygon.getTransformedVertices();
        float[] worldVertices = new float[vertices.length];

        for (int i = 0; i < vertices.length; ++i) {
            worldVertices[i] = Physics.toUnits(vertices[i]);
        }

        polygonShape.set(worldVertices);

        return polygonShape;
    }

    public static ChainShape getPolyline(PolylineMapObject polylineObject) {
        return getPolyline(polylineObject.getPolyline());
    }

    public static ChainShape getPolyline(Polyline polyline) {
        ChainShape chain = new ChainShape();

        float[] vertices = polyline.getTransformedVertices();
        Vector2[] worldVertices = new Vector2[vertices.length / 2];

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

        chain.createChain(worldVertices);

        return chain;
    }
}

Because I use Ashley (an Entity Component System created for libGDX), I create a system which converts all MapObjects from my map's Collision layer into bodies:

public class TiledMapCollisionSystem extends EntitySystem {

    public TiledMapCollisionSystem() {
        MapObjects objects = LevelManager.getActiveMap().getLayers().get(Layers.COLLISION).getObjects();

        for (MapObject object : objects) {
            if (object instanceof TextureMapObject) {
                continue;
            }

            Shape shape;

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

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

            shape.dispose();
        }
    }
}

Note that the map is already loaded and the Box2D world is already created before the system is instantiated. Layers.COLLISION is a simple constant String "Collision". You don't need to create a System if you aren't using Ashley, as you can simply create another utility class which does the same thing.