package fr.umlv.escapeir.physic;
import java.awt.Point;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.FixtureDef;
import fr.umlv.escapeir.EscapeIR;
/**
* Handle the conversion between pixelated world (zen2) and physical world (JBox2D)
* @author Joachim ARCHAMBAULT, Alexandre ANDRE
*/
public class World {
public static org.jbox2d.dynamics.World WORLD;
//Yeah we are in space, the safety distance isn't "two white highway stripes"
//So yes 1 meter is about 10 pixels
/**
* Sets the conversion of one meter in pixels
*/
public static final int METER2PIXEL = 10;
/**
* Sets the horizontal offset
*/
public static final int X_OFFSET = 0;
/**
* Sets the vertical offset
*/
public static final int Y_OFFSET = 60;
/**
* Computes the real world width based on the pixelated width
*/
public static final int WIDTH = EscapeIR.WIDTH / World.METER2PIXEL;
/**
* Computes the real world height based on the pixelated height
*/
public static final int HEIGHT = EscapeIR.HEIGHT / World.METER2PIXEL;
/**
* Creates a physical world with a given gravity, and walls on each windows borders
* @param gravity The gravity used in this world
*/
public World(Vec2 gravity) {
World.WORLD = new org.jbox2d.dynamics.World(gravity, true);
World.WORLD.setContinuousPhysics(true);
Vec2 hSize = new Vec2(World.WIDTH, 1);
Vec2 vSize = new Vec2(1, World.HEIGHT);
World.WORLD.setContactListener(new Collision());
//Top World Wall
this.createWall(new Vec2(0, World.HEIGHT - 1), hSize);
//Bottom World Wall
this.createWall(new Vec2(0, 0), hSize);
//Left World Wall
this.createWall(new Vec2(0, 0), vSize);
//Right World Wall
this.createWall(new Vec2(World.WIDTH, 0), vSize);
}
/**
* Creates a wall with a given size at the given position
* @param position
* @param size
*/
private void createWall(Vec2 position, Vec2 size) {
PolygonShape wallShape = new PolygonShape();
wallShape.setAsBox(size.x, size.y);
FixtureDef wallFixture = new FixtureDef();
wallFixture.shape = wallShape;
wallFixture.density = 1;
wallFixture.restitution = 0;
BodyDef wallBodyDef = new BodyDef();
wallBodyDef.type = BodyType.STATIC;
wallBodyDef.position = position;
World.WORLD.createBody(wallBodyDef).createFixture(wallFixture);
}
/**
* Instantiate a Point based on a Vec2
* Ensure the conversion from physical world to pixelated world
* @param vector The vector to convert
* @return A Point in the pixelated world
*/
public static Point toPixel(Vec2 vector) {
int x = (int) ((vector.x + World.X_OFFSET) * World.METER2PIXEL);
int y = (int) ((-vector.y + World.Y_OFFSET) * World.METER2PIXEL);
return new Point(x, y);
}
/**
* Instantiate a Vec2 based on a Point
* Ensure the conversion from pixelated world to physical world
* @param point The point to convert
* @return A Vec2 in the physical world
*/
public static Vec2 toWorld(Point point) {
float x = (float) ((point.getX() / World.METER2PIXEL) - World.X_OFFSET);
float y = (float) ((point.getY() / World.METER2PIXEL) - World.Y_OFFSET);
if (y < 0)
y = -y;
return new Vec2(x, y);
}
/**
* Return the vector based on the angle of to given points
* @param from The initial point
* @param to The terminal point
* @return A Vec2 representing the angle between two points
*/
public static Vec2 angle(Point from, Point to) {
Vec2 fromVec = World.toWorld(from);
Vec2 toVec = World.toWorld(to);
return new Vec2(toVec.x - fromVec.x, toVec.y - fromVec.y);
}
}