package advanced.physics.scenes; import java.util.ArrayList; import java.util.List; import org.jbox2d.collision.AABB; import org.jbox2d.common.Vec2; import org.jbox2d.dynamics.World; import org.mt4j.MTApplication; import org.mt4j.components.MTComponent; import org.mt4j.input.inputProcessors.globalProcessors.CursorTracer; import org.mt4j.sceneManagement.AbstractScene; import org.mt4j.util.MTColor; import org.mt4j.util.math.ToolsMath; import org.mt4j.util.math.Vector3D; import org.mt4j.util.math.Vertex; import advanced.physics.physicsShapes.PhysicsCircle; import advanced.physics.physicsShapes.PhysicsPolygon; import advanced.physics.physicsShapes.PhysicsRectangle; import advanced.physics.util.PhysicsHelper; import advanced.physics.util.UpdatePhysicsAction; public class PhysicsScene extends AbstractScene { private float timeStep = 1.0f / 60.0f; private int constraintIterations = 10; /** THE CANVAS SCALE **/ private float scale = 20; private MTApplication app; private World world; private MTComponent physicsContainer; public PhysicsScene(MTApplication mtApplication, String name) { super(mtApplication, name); this.app = mtApplication; float worldOffset = 10; //Make Physics world slightly bigger than screen borders //Physics world dimensions AABB worldAABB = new AABB(new Vec2(-worldOffset, -worldOffset), new Vec2((app.width)/scale + worldOffset, (app.height)/scale + worldOffset)); Vec2 gravity = new Vec2(0, 10); // Vec2 gravity = new Vec2(0, 0); boolean sleep = true; //Create the pyhsics world this.world = new World(worldAABB, gravity, sleep); this.registerGlobalInputProcessor(new CursorTracer(app, this)); //Update the positions of the components according the the physics simulation each frame this.registerPreDrawAction(new UpdatePhysicsAction(world, timeStep, constraintIterations, scale)); physicsContainer = new MTComponent(app); //Scale the physics container. Physics calculations work best when the dimensions are small (about 0.1 - 10 units) //So we make the display of the container bigger and add in turn make our physics object smaller physicsContainer.scale(scale, scale, 1, Vector3D.ZERO_VECTOR); this.getCanvas().addChild(physicsContainer); //Create borders around the screen this.createScreenBorders(physicsContainer); //Createa circles for (int i = 0; i < 20; i++) { PhysicsCircle c = new PhysicsCircle(app, new Vector3D(ToolsMath.getRandom(60, mtApplication.width-60), ToolsMath.getRandom(60, mtApplication.height-60)), 50, world, 1.0f, 0.3f, 0.4f, scale); MTColor col = new MTColor(ToolsMath.getRandom(60, 255),ToolsMath.getRandom(60, 255),ToolsMath.getRandom(60, 255)); c.setFillColor(col); c.setStrokeColor(col); PhysicsHelper.addDragJoint(world, c, c.getBody().isDynamic(), scale); physicsContainer.addChild(c); } //Create rectangle PhysicsRectangle physRect = new PhysicsRectangle(new Vector3D(100,300), 100, 50, app, world, 1f, 0.4f, 0.4f, scale); MTColor col = new MTColor(ToolsMath.getRandom(60, 255),ToolsMath.getRandom(60, 255),ToolsMath.getRandom(60, 255)); physRect.setFillColor(col); physRect.setStrokeColor(col); PhysicsHelper.addDragJoint(world, physRect, physRect.getBody().isDynamic(), scale); physicsContainer.addChild(physRect); //Create polygon Vertex[] polyVertices = new Vertex[]{ new Vertex(-10,0,0), new Vertex(10,0,0), new Vertex(10,50,0), new Vertex(60,50,0), new Vertex(60,70,0), new Vertex(10,70,0), new Vertex(10,120,0), new Vertex(-10,120,0), new Vertex(-10,70,0), new Vertex(-60,70,0), new Vertex(-60,50,0), new Vertex(-10,50,0), new Vertex(-10,0,0), }; PhysicsPolygon physPoly = new PhysicsPolygon(polyVertices, new Vector3D(250,250), app, world, 1.0f, 0.3f, 0.4f, scale); MTColor polyCol = new MTColor(ToolsMath.getRandom(60, 255),ToolsMath.getRandom(60, 255),ToolsMath.getRandom(60, 255)); physPoly.setFillColor(polyCol); physPoly.setStrokeColor(polyCol); PhysicsHelper.addDragJoint(world, physPoly, physPoly.getBody().isDynamic(), scale); //For an anti-aliased outline List<Vertex[]> contours = new ArrayList<Vertex[]>(); contours.add(polyVertices); physPoly.setOutlineContours(contours); physPoly.setNoStroke(false); physicsContainer.addChild(physPoly); } private void createScreenBorders(MTComponent parent){ //Left border float borderWidth = 50f; float borderHeight = app.height; Vector3D pos = new Vector3D(-(borderWidth/2f) , app.height/2f); PhysicsRectangle borderLeft = new PhysicsRectangle(pos, borderWidth, borderHeight, app, world, 0,0,0, scale); borderLeft.setName("borderLeft"); parent.addChild(borderLeft); //Right border pos = new Vector3D(app.width + (borderWidth/2), app.height/2); PhysicsRectangle borderRight = new PhysicsRectangle(pos, borderWidth, borderHeight, app, world, 0,0,0, scale); borderRight.setName("borderRight"); parent.addChild(borderRight); //Top border borderWidth = app.width; borderHeight = 50f; pos = new Vector3D(app.width/2, -(borderHeight/2)); PhysicsRectangle borderTop = new PhysicsRectangle(pos, borderWidth, borderHeight, app, world, 0,0,0, scale); borderTop.setName("borderTop"); parent.addChild(borderTop); //Bottom border pos = new Vector3D(app.width/2 , app.height + (borderHeight/2)); PhysicsRectangle borderBottom = new PhysicsRectangle(pos, borderWidth, borderHeight, app, world, 0,0,0, scale); borderBottom.setName("borderBottom"); parent.addChild(borderBottom); } @Override public void init() { } @Override public void shutDown() { } }