/**
   * 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()]);
  }
示例#2
0
  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");
    		}
    		*/
  }