예제 #1
0
  /** Updates DisplacementMap and path for current coordinates. */
  public void update() {
    setUpdateNeeded(false);

    if (newWidth == map.getWidth()
        && newHeight == map.getHeight()
        && targetX == oldTargetX
        && targetY == oldTargetY) {
      return;
    }
    oldTargetX = targetX;
    oldTargetY = targetY;
    if (newWidth != map.getWidth() || newHeight != map.getHeight()) {
      map.setWidth(newWidth);
      map.setHeight(newHeight);
    }

    final double W = node.getLayoutBounds().getWidth();
    final double H = node.getLayoutBounds().getHeight();

    // target point F for folded corner
    final double xF = Math.min(targetX, W - 1);
    final double yF = Math.min(targetY, H - 1);

    final Point2D F = new Point2D(xF, yF);

    // corner point O
    final double xO = W;
    final double yO = H;

    // distance between them
    final double FO = Math.hypot(xF - xO, yF - yO);
    final double AF = FO / 2;

    final double AC = Math.min(AF * 0.5, 200);

    // radius of the fold as seen along the l2 line
    final double R = AC / Math.PI * 1.5;
    final double BC = R;
    final double flat_R = AC;

    // Gradient for the line from target point to corner point
    final double K = (yO - yF) / (xO - xF);

    // angle of a line l1
    final double ANGLE = Math.atan(1 / K);

    // point A (on line l1 - the mirror line of target and corner points)
    final double xA = (xO + xF) / 2;
    final double yA = (yO + yF) / 2;

    // end points of line l1
    final double bottomX = xA - (H - yA) * K;
    final double bottomY = H;
    final double rightX = W;
    final double rightY = yA - (W - xA) / K;

    final Point2D RL1 = new Point2D(rightX, rightY);
    final Point2D BL1 = new Point2D(bottomX, bottomY);

    // point C (on line l2 - the line when distortion begins)
    final double kC = AC / AF;
    final double xC = xA - (xA - xF) * kC;
    final double yC = yA - (yA - yF) * kC;

    final Point2D C = new Point2D(xC, yC);

    final Point2D RL2 = new Point2D(W, yC - (W - xC) / K);
    final Point2D BL2 = new Point2D(xC - (H - yC) * K, H);

    // point B (on line l3 - the line where distortion ends)
    final double kB = BC / AC;
    final double xB = xC + (xA - xC) * kB;
    final double yB = yC + (yA - yC) * kB;

    // Bottom ellipse calculations
    final Point2D BP1 = calcIntersection(F, BL1, BL2, C);
    final Point2D BP3 = BL2;
    final Point2D BP2 = middle(BP1, BP3, 0.5);
    final Point2D BP4 = new Point2D(xB + BP2.getX() - xC, yB + BP2.getY() - yC);

    final double bE_x1 = hypot(BP2, BP3);
    final double bE_y2 = -hypot(BP2, BP4);
    final double bE_yc = -hypot(BP2, BL1);
    final double bE_y0 = bE_y2 * bE_y2 / (2 * bE_y2 - bE_yc);
    final double bE_b = bE_y0 - bE_y2;
    final double bE_a = Math.sqrt(-bE_x1 * bE_x1 / bE_y0 * bE_b * bE_b / bE_yc);

    // Right ellipse calculations
    final Point2D RP1 = calcIntersection(F, RL1, RL2, C);
    final Point2D RP3 = RL2;
    final Point2D RP2 = middle(RP1, RP3, 0.5);
    final Point2D RP4 = new Point2D(xB + RP2.getX() - xC, yB + RP2.getY() - yC);

    final double rE_x1 = hypot(RP2, RP3);
    final double rE_y2 = -hypot(RP2, RP4);
    final double rE_yc = -hypot(RP2, RL1);
    final double rE_y0 = rE_y2 * rE_y2 / (2 * rE_y2 - rE_yc);
    final double rE_b = rE_y0 - rE_y2;
    final double rE_a = Math.sqrt(-rE_x1 * rE_x1 / rE_y0 * rE_b * rE_b / rE_yc);

    p.setFill(
        new LinearGradient(
            xF,
            yF,
            xO,
            yO,
            false,
            CycleMethod.NO_CYCLE,
            new Stop(0, pathColor),
            new Stop((xC - xF) / (xO - xF), bendStartColor),
            new Stop((xB - xF) / (xO - xF), bendEndColor)));

    p.getElements()
        .setAll(
            new MoveTo(BP4.getX(), BP4.getY()),
            ArcToBuilder.create()
                .XAxisRotation(Math.toDegrees(-ANGLE))
                .radiusX(bE_a)
                .radiusY(bE_b)
                .x(BP1.getX())
                .y(BP1.getY())
                .build(),
            new LineTo(xF, yF),
            new LineTo(RP1.getX(), RP1.getY()),
            ArcToBuilder.create()
                .XAxisRotation(Math.toDegrees(-ANGLE))
                .radiusX(rE_a)
                .radiusY(rE_b)
                .x(RP4.getX())
                .y(RP4.getY())
                .build(),
            new ClosePath());

    if (shadow != null) {
      double level0 = (xB - xF) / (xO - xF) - R / FO * 0.5;
      double level1 = (xB - xF) / (xO - xF) + (0.3 + (200 - AC) / 200) * R / FO;
      shadow.setFill(
          new LinearGradient(
              xF,
              yF,
              xO,
              yO,
              false,
              CycleMethod.NO_CYCLE,
              new Stop(level0, Color.rgb(0, 0, 0, 0.7)),
              new Stop(level0 * 0.3 + level1 * 0.7, Color.rgb(0, 0, 0, 0.25)),
              new Stop(level1, Color.rgb(0, 0, 0, 0.0)),
              new Stop(1, Color.rgb(0, 0, 0, 0))));

      shadow
          .getElements()
          .setAll(
              new MoveTo(RP3.getX(), RP3.getY()),
              ArcToBuilder.create()
                  .XAxisRotation(Math.toDegrees(-ANGLE))
                  .radiusX(rE_a)
                  .radiusY(rE_b)
                  .x(RP4.getX())
                  .y(RP4.getY())
                  .sweepFlag(true)
                  .build(),
              new LineTo(BP4.getX(), BP4.getY()),
              ArcToBuilder.create()
                  .XAxisRotation(Math.toDegrees(-ANGLE))
                  .radiusX(bE_a)
                  .radiusY(bE_b)
                  .x(BP3.getX())
                  .y(BP3.getY())
                  .sweepFlag(true)
                  .build(),
              new LineTo(xO, yO),
              new ClosePath());
    }

    if (clip != null) {
      final Point2D RL3 = new Point2D(W, yB - (W - xB) / K);
      final Point2D BL3 = new Point2D(xB - (H - yB) * K, H);

      clip.getElements()
          .setAll(
              new MoveTo(0, 0),
              RL3.getY() > 0 ? new LineTo(W, 0) : new LineTo(0, 0),
              RL3.getY() >= 0
                  ? new LineTo(RL3.getX(), RL3.getY())
                  : new LineTo(xB - (0 - yB) * K, 0),
              BL3.getX() >= 0
                  ? new LineTo(BL3.getX(), BL3.getY())
                  : new LineTo(0, yB - (0 - xB) / K),
              BL3.getX() > 0 ? new LineTo(0, H) : new LineTo(0, 0),
              new ClosePath());
    }

    final double K2 = -K;
    final double C2 = BP3.getX() - K2 * H;

    final double K3 = -K;
    final double C3 = xB - K3 * yB;

    final double STEP = Math.max(0.1, R / (buffer.length - 1));
    final double HYPOT = Math.hypot(1, K);
    final double yR = 1.5 * R;
    double x_1 = 0, y_1 = 0, cur_len = 0;
    for (double len = 0; len <= R; len += STEP) {
      final int index = (int) Math.round(len / STEP);
      final double angle = Math.asin(len / R);
      final double y = yR * Math.cos(angle);
      if (len > 0) {
        cur_len += Math.hypot(y - y_1, len - x_1);
      }
      buffer[index][0] = (float) angle;
      buffer[index][1] = (float) (cur_len * flat_R);
      x_1 = len;
      y_1 = y;
    }
    double total_len = cur_len;
    for (double len = 0; len <= R; len += STEP) {
      final int index = (int) Math.round(len / STEP);
      final double flat_len = buffer[index][1] / total_len;
      final double delta_len = flat_len - len;
      final double xs = delta_len / HYPOT;
      final double ys = K * delta_len / HYPOT;
      buffer[index][0] = (float) (xs / W);
      buffer[index][1] = (float) (ys / H);
    }

    for (int y = 0; y < map.getHeight(); y++) {
      final double lx2 = K2 * (y + 0.5) + C2;
      final double lx3 = K3 * (y + 0.5) + C3;
      for (int x = 0; x < map.getWidth(); x++) {
        if (x + 0.5 < lx2) {
          map.setSamples(x, y, 0, 0);
        } else if (x + 0.5 >= lx3 - 1) {
          map.setSamples(x, y, 1, 0);
        } else {
          final double len = Math.abs((x + 0.5) - K2 * (y + 0.5) - C2) / HYPOT;
          final int index = (int) Math.round(len / STEP);
          map.setSamples(x, y, buffer[index][0], buffer[index][1]);
        }
      }
    }
  }
예제 #2
0
  private void render() {
    ArrayList<NetworkMessage> messages = networkController.getMessages();

    for (NetworkMessage message : messages) {
      String messageType =
          message.getClass().getName().replace("NetworkMessages.", "").replace("Messages.", "");
      switch (messageType) {
        case "PelletPositionMessage":
          {
            PelletPositionMessage m = (PelletPositionMessage) message;
            Drawable drawable = getCachedDrawable(m.id);
            if (drawable != null) {
              drawable.node.relocate(m.x, m.y);
              drawable.cacheMisses = 0;
            } else {
              Random r = new Random();
              Node node =
                  drawCircle(
                      m.x, m.y, 5, new Color(r.nextFloat(), r.nextFloat(), r.nextFloat(), 1));
              drawableCache.add(new Drawable(m.id, node));
            }
          }
          break;
        case "BlobStateMessage":
          {
            BlobStateMessage m = (BlobStateMessage) message;
            Color color = Color.web(m.color);
            Node node;
            if (color.getBrightness() != 0) {
              node = drawCircle(m.x, m.y, m.size / 2, color);
            } else {
              node = drawCircle(m.x, m.y, m.size / 2, color.brighter().brighter());
            }
            Node nameText =
                drawText((m.x - m.username.length() * 5), (m.y - m.size / 2), m.username, color);
            Drawable drawable = getCachedDrawable(m.id);
            if (drawable != null) {
              node.setLayoutX((drawable.node.getTranslateX() - m.x) / 10000);
              node.setLayoutY((drawable.node.getTranslateY() - m.y) / 10000);
              drawable.node = node;
              drawable.cacheMisses = 0;
              Drawable nameTag = getCachedDrawable(m.id + 9000);
              nameTag.node = nameText;
              nameTag.cacheMisses = 0;
            } else {
              drawableCache.add(new Drawable(m.id, node));
              drawableCache.add(new Drawable(m.id + 9000, nameText));
            }
          }
          break;
        case "PingMessage":
          {
            renderPane.getChildren().clear();
            ArrayList<Drawable> drawables = new ArrayList<>(drawableCache);
            for (Drawable drawable : drawables) {
              if (drawable.cacheMisses > 1) {
                drawableCache.remove(drawable);
              }
              drawable.cacheMisses++;
              renderPane.getChildren().add(drawable.node);
            }
            renderPane.getChildren().addAll(chatBox, chatInput, lagLabel, scores);

            lag = System.currentTimeMillis() - lastReceivedTime;
            lastReceivedTime = System.currentTimeMillis();
            lagLabel.setText("Net Lag: " + Long.toString(lag));
          }
          break;
        case "HighScoreMessage":
          {
            HighScoreMessage m = (HighScoreMessage) message;
            highScores.setText("HIGH SCORES:" + m.text);
          }
          break;
        case "CurrentScoreMessage":
          {
            CurrentScoreMessage m = (CurrentScoreMessage) message;
            currentScores.setText("Current Scores:" + m.text);
          }
          break;
        case "ChatMessage":
          {
            ChatMessage m = (ChatMessage) message;
            chatBox.appendText(m.username + "> " + m.text + "\n");
          }
          break;
      }
    }
  }