package loon.physics; import loon.LTexture; import loon.action.collision.CollisionMask; import loon.canvas.Image; import loon.geom.Circle; import loon.geom.Polygon; import loon.geom.RectBox; import loon.geom.Vector2f; import loon.utils.CollectionUtils; public class PPhysManager { public float scale; public float offX; public float offY; public PPhysWorld world; public boolean start; public boolean enableGravity; public Vector2f gravity; private boolean isCenterPos = false; public PPhysManager() { this(50F); } public PPhysManager(float s) { this(s, 0.0F, 9.80665F); } public PPhysManager(float s, float gx, float gy) { this.world = new PPhysWorld(); this.gravity = new Vector2f(gx, gy); this.start = false; this.enableGravity = true; this.scale = s; } public PBody addBody(PBody body) { world.addBody(body); return body; } public PBody box(boolean fix, float x, float y, float w, float h, float angle, float density) { PBody body = null; if (!isCenterPos) { body = new PBody(angle, fix, new PShape[] { new PBoxShape( (x + w / 2) / scale, (y + h / 2) / scale, w / scale, h / scale, angle, density) }); } else { body = new PBody(angle, fix, new PShape[] { new PBoxShape(x / scale, y / scale, w / scale, h / scale, angle, density) }); } return body; } public PBody box(boolean fix, RectBox rect, float angle, float density) { return box(fix, rect.x, rect.y, (float) rect.width, (float) rect.height, angle, density); } public PBody addBox(boolean fix, float x, float y, float w, float h, float angle, float density) { PBody body = box(fix, x, y, w, h, angle, density); world.addBody(body); return body; } public PBody addBox(boolean fix, float x, float y, float w, float h) { return addBox(fix, x, y, w, h, 0F, 1F); } public PBody addBox(boolean fix, RectBox rect, float angle, float density) { PBody body = box(fix, rect, angle, density); world.addBody(body); return body; } public PBody addBox(boolean fix, RectBox rect) { return addBox(fix, rect, 0F, 1F); } public PBody circle(boolean fix, float x, float y, float r, float angle, float density) { PBody body = null; if (!isCenterPos) { body = new PBody(angle, fix, new PShape[] { new PCircleShape(x / scale, y / scale, r / scale, angle, density) }); } else { body = new PBody(angle, fix, new PShape[] { new PCircleShape(x / scale, y / scale, r / scale, angle, density) }); } return body; } public PBody circle(boolean fix, Circle c, float angle, float density) { return circle(fix, c.x, c.y, c.radius, angle, density); } public PBody addCircle(boolean fix, float x, float y, float r, float angle, float density) { PBody body = circle(fix, x, y, r, angle, density); world.addBody(body); return body; } public PBody addCircle(boolean fix, float x, float y, float r, float angle) { return addCircle(fix, x, y, r, angle, 1F); } public PBody addCircle(boolean fix, float x, float y, float r) { return addCircle(fix, x, y, r, 0F, 1F); } public PBody polygon(boolean fix, Polygon p, float angle, float density) { PPolygon tmp = p.getPPolygon(this.scale); PConcavePolygonShape shape = new PConcavePolygonShape(tmp.xs, tmp.ys, density); PBody body = new PBody(angle, fix, new PShape[] { shape }); return body; } public PBody polygon(boolean fix, float[] xs, float[] ys, int num, float angle, float density) { if (num < 3) { return null; } if (xs.length != num) { xs = CollectionUtils.copyOf(xs, num); } if (ys.length != num) { ys = CollectionUtils.copyOf(ys, num); } for (int i = 0; i < num; i++) { xs[i] /= scale; ys[i] /= scale; } PConcavePolygonShape shape = new PConcavePolygonShape(xs, ys, density); PBody body = new PBody(angle, fix, new PShape[] { shape }); return body; } public PBody addPolygon(boolean fix, float[] xs, float[] ys, int num) { return addPolygon(fix, xs, ys, num, 0F, 1F); } public PBody addPolygon(boolean fix, float[] xs, float[] ys, int num, float angle, float density) { PBody body = polygon(fix, xs, ys, num, angle, density); world.addBody(body); return body; } public PBody addPolygon(boolean fix, Polygon p) { return addPolygon(fix, p, 0F, 1F); } public PBody addPolygon(boolean fix, Polygon p, float angle, float density) { PBody body = polygon(fix, p, angle, density); world.addBody(body); return body; } public PBody shape(boolean fix, PShape shape, float angle, float density) { PBody body = new PBody(angle, fix, new PShape[] { shape }); return body; } public PBody shape(boolean fix, PShape shape) { return shape(fix, shape, 0F, 1F); } public PBody addShape(boolean fix, PShape shape, float angle, float density) { PBody body = shape(fix, shape, angle, density); world.addBody(body); return body; } public PBody addShape(boolean fix, PShape shape) { return addShape(fix, shape, 0F, 1F); } public PBody addShape(boolean fix, Image shape) { Polygon polygon = CollisionMask.makePolygon(shape); return addPolygon(fix, polygon); } public PBody addShape(boolean fix, Image shape, float angle, float density) { Polygon polygon = CollisionMask.makePolygon(shape); return addPolygon(fix, polygon, angle, density); } public PBody addShape(boolean fix, LTexture shape, float angle, float density) throws Exception { Image image = shape.getImage(); Polygon polygon = null; if (image == null) { throw new Exception("the texture are image is null"); } else { polygon = CollisionMask.makePolygon(image); } return addPolygon(fix, polygon, angle, density); } public float getWorldX(float sx) { return (sx - this.offX) / this.scale; } public float getWorldY(float sy) { return (sy - this.offY) / this.scale; } public float getScreenX(float wx) { return wx * this.scale + this.offX; } public float getScreenY(float wy) { return wy * this.scale + this.offY; } public void panScreen(float px, float py) { this.offX += px; this.offY += py; } public void offset(float px, float py) { this.offX = px; this.offY = py; } public void zoomScreen(float zoom, float cx, float cy) { float px = -getWorldX(cx); float py = -getWorldY(cy); this.scale *= zoom; px += getWorldX(cx); py += getWorldY(cy); panScreen(px * this.scale, py * this.scale); } public void step(float dt) { if (enableGravity) { world.setGravity(gravity.x, gravity.y); } else { world.setGravity(0.0F, 0.0F); } if (start) { world.step(dt); } else { world.update(); } } public PPhysWorld getWorld() { return world; } public void setWorld(PPhysWorld world) { this.world = world; } public boolean isStart() { return start; } public void setStart(boolean start) { this.start = start; } public boolean isEnableGravity() { return enableGravity; } public void setEnableGravity(boolean enableGravity) { this.enableGravity = enableGravity; } public Vector2f getGravity() { return gravity; } public void setGravity(Vector2f gravity) { this.gravity = gravity; } public float getScale() { return scale; } public void setScale(float scale) { this.scale = scale; } public float getOffX() { return offX; } public void setOffX(float offX) { this.offX = offX; } public float getOffY() { return offY; } public void setOffY(float offY) { this.offY = offY; } public boolean isCenterPos() { return isCenterPos; } public void setCenterPos(boolean isCenterPos) { this.isCenterPos = isCenterPos; } }