/** * Constructor. * * @param pApplet - the parent PApplet * @param centerX - the center x coordinate of the annular ring, that is the point in the center * of the annulus if it were complete. * @param centerY - the center y coordinate of the ring. * @param innerRadius - the inner radius of the annular band. * @param outerRadius - the outer radius. * @param startAngle - the starting angle in degrees. * @param endAngle - the ending angle in degrees. * @param segments - the number of line segments to use in simulating arcs for every PI/2 radians * of arc. The number of segments actually used will generally be different. */ public MTAnnularSegment( PApplet pApplet, float centerX, float centerY, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments) { super( pApplet, computeVertices( new Vector3D(centerX, centerY, 0f), innerRadius, outerRadius, startAngle, endAngle, segments)); this.centerPoint = new Vector3D(centerX, centerY, 0f); // Ensure they're not swapped by accident. this.innerRadius = Math.min(innerRadius, outerRadius); this.outerRadius = Math.max(innerRadius, outerRadius); // Ensure that these angles are in the range [0 - 360]. this.startAngle = fixAngle(startAngle); this.endAngle = fixAngle(endAngle); // Get the vertices in order to generate polygons and lines. Vertex[] vertices = this.getGeometryInfo().getVertices(); // The segments argument is the number of segments per 90 degrees. // The actual number is probably different. segments = (vertices.length - 2) / 2; // Generate a trapezoid for each segment. polygons = new MTPolygon[segments]; for (int i = 0; i < segments; i++) { polygons[i] = new MTPolygon( pApplet, new Vertex[] { vertices[i], vertices[i + 1], vertices[vertices.length - i - 2], vertices[vertices.length - i - 1] }); polygons[i].setPickable(false); polygons[i].setNoStroke(true); polygons[i].setFillColor(super.getFillColor()); this.addChild(polygons[i]); } // Is it a complete ring? boolean fullCircle = this.startAngle == this.endAngle; List<MTLine> lines = new ArrayList<MTLine>(fullCircle ? vertices.length : vertices.length - 2); // The outer lines. for (int i = 0; i < segments; i++) { Vertex start = vertices[i]; Vertex end = vertices[i + 1]; MTLine line = new MTLine(pApplet, start, end); line.setStrokeColor(super.getStrokeColor()); line.setStrokeWeight(super.getStrokeWeight()); line.setPickable(false); this.addChild(line); lines.add(line); } // If not a complete ring, generate the line on one end. if (!fullCircle) { Vertex start = vertices[segments]; Vertex end = vertices[segments + 1]; MTLine line = new MTLine(pApplet, start, end); line.setStrokeColor(super.getStrokeColor()); line.setStrokeWeight(super.getStrokeWeight()); line.setPickable(false); this.addChild(line); lines.add(line); } // Now the lines on the inner ring. int lim = 2 * segments + 1; for (int i = segments + 1; i < lim; i++) { Vertex start = vertices[i]; Vertex end = vertices[i + 1]; MTLine line = new MTLine(pApplet, start, end); line.setStrokeColor(super.getStrokeColor()); line.setStrokeWeight(super.getStrokeWeight()); line.setPickable(false); this.addChild(line); lines.add(line); } // The final end line if not a complete ring. if (!fullCircle) { Vertex start = vertices[vertices.length - 1]; Vertex end = vertices[0]; MTLine line = new MTLine(pApplet, start, end); line.setStrokeColor(super.getStrokeColor()); line.setStrokeWeight(super.getStrokeWeight()); line.setPickable(false); this.addChild(line); lines.add(line); } outlines = lines.toArray(new MTLine[lines.size()]); }
public AirHockeyScene(AbstractMTApplication mtApplication, String name) { super(mtApplication, name); this.app = mtApplication; // this.setClearColor(new MTColor(120,150,150)); // this.setClearColor(new MTColor(190, 190, 170, 255)); this.setClearColor(new MTColor(0, 0, 0, 255)); // this.setClearColor(new MTColor(40, 40, 40, 255)); this.registerGlobalInputProcessor(new CursorTracer(app, this)); this.scorePlayer1 = 0; this.scorePlayer2 = 0; 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, 0); boolean sleep = true; // Create the pyhsics world this.world = new World(worldAABB, gravity, sleep); // 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); // Create gamefield marks MTLine line = new MTLine( mtApplication, mtApplication.width / 2f / scale, 0, mtApplication.width / 2f / scale, mtApplication.height / scale); line.setPickable(false); // line.setStrokeColor(new MTColor(0,0,0)); line.setStrokeColor(new MTColor(150, 150, 150)); line.setStrokeWeight(0.5f); physicsContainer.addChild(line); MTEllipse centerCircle = new MTEllipse( mtApplication, new Vector3D(mtApplication.width / 2f / scale, mtApplication.height / 2f / scale), 80 / scale, 80 / scale); centerCircle.setPickable(false); centerCircle.setNoFill(true); // centerCircle.setStrokeColor(new MTColor(0,0,0)); centerCircle.setStrokeColor(new MTColor(150, 150, 150)); centerCircle.setStrokeWeight(0.5f); physicsContainer.addChild(centerCircle); MTEllipse centerCircleInner = new MTEllipse( mtApplication, new Vector3D(mtApplication.width / 2f / scale, mtApplication.height / 2f / scale), 10 / scale, 10 / scale); centerCircleInner.setPickable(false); centerCircleInner.setFillColor(new MTColor(160, 160, 160)); // centerCircleInner.setStrokeColor(new MTColor(150,150,150)); // centerCircleInner.setStrokeColor(new MTColor(0,0,0)); centerCircleInner.setStrokeColor(new MTColor(150, 150, 150)); centerCircleInner.setStrokeWeight(0.5f); physicsContainer.addChild(centerCircleInner); // Create the paddles PImage paddleTex = mtApplication.loadImage(imagesPath + "paddle.png"); redCircle = new Paddle( app, new Vector3D(mtApplication.width - 60, mtApplication.height / 2f), 50, world, 1.0f, 0.3f, 0.4f, scale); redCircle.setTexture(paddleTex); redCircle.setFillColor(new MTColor(255, 50, 50)); redCircle.setNoStroke(true); redCircle.setName("red"); redCircle.setPickable(false); physicsContainer.addChild(redCircle); blueCircle = new Paddle( app, new Vector3D(80, mtApplication.height / 2f), 50, world, 1.0f, 0.3f, 0.4f, scale); blueCircle.setTexture(paddleTex); blueCircle.setFillColor(new MTColor(50, 50, 255)); blueCircle.setNoStroke(true); blueCircle.setName("blue"); blueCircle.setPickable(false); physicsContainer.addChild(blueCircle); // Create the ball ball = new HockeyBall( app, new Vector3D(mtApplication.width / 2f, mtApplication.height / 2f), 38, world, 0.5f, 0.005f, 0.70f, scale); // MTColor ballCol = new MTColor(0,255,0); // ball.setFillColor(ballCol); PImage ballTex = mtApplication.loadImage(imagesPath + "puk.png"); ball.setTexture(ballTex); // ball.setFillColor(new MTColor(160,160,160,255)); ball.setFillColor(new MTColor(255, 255, 255, 255)); ball.setNoStroke(true); ball.setName("ball"); physicsContainer.addChild(ball); ball.getBody() .applyImpulse( new Vec2(ToolsMath.getRandom(-8f, 8), ToolsMath.getRandom(-8, 8)), ball.getBody().getWorldCenter()); // Create the GOALS HockeyGoal goal1 = new HockeyGoal( new Vector3D(0, mtApplication.height / 2f), 50, mtApplication.height / 4f, mtApplication, world, 0.0f, 0.1f, 0.0f, scale); goal1.setName("goal1"); goal1.setFillColor(new MTColor(0, 0, 255)); goal1.setStrokeColor(new MTColor(0, 0, 255)); physicsContainer.addChild(goal1); HockeyGoal goal2 = new HockeyGoal( new Vector3D(mtApplication.width, mtApplication.height / 2f), 50, mtApplication.height / 4f, mtApplication, world, 0.0f, 0.1f, 0.0f, scale); goal2.setName("goal2"); goal2.setFillColor(new MTColor(255, 0, 0)); goal2.setStrokeColor(new MTColor(255, 0, 0)); physicsContainer.addChild(goal2); // Make two components for both game field sides to drag the puks upon MTRectangle leftSide = new MTRectangle( app, PhysicsHelper.scaleDown(0, scale), PhysicsHelper.scaleDown(0, scale), PhysicsHelper.scaleDown(app.width / 2f, scale), PhysicsHelper.scaleDown(app.height, scale)); leftSide.setName("left side"); leftSide.setNoFill(true); // Make it invisible -> only used for dragging leftSide.setNoStroke(true); leftSide.unregisterAllInputProcessors(); leftSide.removeAllGestureEventListeners(DragProcessor.class); leftSide.registerInputProcessor(new DragProcessor(app)); leftSide.addGestureListener(DragProcessor.class, new GameFieldHalfDragListener(blueCircle)); physicsContainer.addChild(0, leftSide); MTRectangle rightSide = new MTRectangle( app, PhysicsHelper.scaleDown(app.width / 2f, scale), PhysicsHelper.scaleDown(0, scale), PhysicsHelper.scaleDown(app.width, scale), PhysicsHelper.scaleDown(app.height, scale)); rightSide.setName("right Side"); rightSide.setNoFill(true); // Make it invisible -> only used for dragging rightSide.setNoStroke(true); rightSide.unregisterAllInputProcessors(); rightSide.removeAllGestureEventListeners(DragProcessor.class); rightSide.registerInputProcessor(new DragProcessor(app)); rightSide.addGestureListener(DragProcessor.class, new GameFieldHalfDragListener(redCircle)); physicsContainer.addChild(0, rightSide); // Display Score UI MTComponent uiLayer = new MTComponent(mtApplication, new MTCamera(mtApplication)); uiLayer.setDepthBufferDisabled(true); getCanvas().addChild(uiLayer); IFont font = FontManager.getInstance().createFont(mtApplication, "arial", 50, MTColor.WHITE); t1 = new MTTextArea(mtApplication, font); t1.setPickable(false); t1.setNoFill(true); t1.setNoStroke(true); t1.setPositionGlobal(new Vector3D(5, 30, 0)); uiLayer.addChild(t1); t2 = new MTTextArea(mtApplication, font); t2.setPickable(false); t2.setNoFill(true); t2.setNoStroke(true); t2.setPositionGlobal(new Vector3D(mtApplication.width - 65, 30, 0)); uiLayer.addChild(t2); this.updateScores(); // Set up check for collisions between objects this.addWorldContactListener(world); /* //Sound if (enableSound){ minim = new Minim(mtApplication); wallHit = minim.loadSnippet(MT4jSettings.getInstance().getDataFolderPath() + "sound" + File.separator + "paddleBallHit.wav"); // paddleBallClash = minim.loadSample(MT4jSettings.getInstance().getDataFolderPath() + "sound" + File.separator + "paddleBallHit.wav", 2048); // goalHit = minim.loadSnippet(MT4jSettings.getInstance().getDataFolderPath() + "sound" + File.separator + "goal.wav"); // goalHit.play(); paddleHit = minim.loadSnippet(MT4jSettings.getInstance().getDataFolderPath() + "sound" + File.separator + "wallHit.wav"); } */ }