示例#1
0
  /**
   * A generalized Pong AI player. Takes a Rect object and a Ball, computes where the ball will be
   * when ball.y == rect.y, and tries to move toward that x-coordinate. If the ball is moving
   * straight it will try to clip the ball with the edge of the paddle.
   *
   * @param cpu
   */
  private void aiPrediction(Paddle cpu, Paddle opponent) {
    Ball ball = new Ball(mBall);

    // Special case: move torward the center if the ball is blinking
    if (mBall.serving()) {
      cpu.destination = getWidth() / 2;
      cpu.move(true);
      return;
    }

    // Something is wrong if vy = 0.. let's wait until things fix themselves
    if (ball.vy == 0) return;

    // Y-Distance from ball to Rect 'cpu'
    float cpuDist = Math.abs(ball.y - cpu.centerY());
    // Y-Distance to opponent.
    float oppDist = Math.abs(ball.y - opponent.centerY());

    // Distance between two paddles.
    float paddleDistance = Math.abs(cpu.centerY() - opponent.centerY());

    // Is the ball coming at us?
    boolean coming =
        (cpu.centerY() < ball.y && ball.vy < 0) || (cpu.centerY() > ball.y && ball.vy > 0);

    // Total amount of x-distance the ball covers
    float total =
        ((((coming) ? cpuDist : oppDist + paddleDistance)) / Math.abs(ball.vy)) * Math.abs(ball.vx);

    // Playable width of the stage
    float playWidth = getWidth() - 2 * Ball.RADIUS;

    float wallDist = (ball.goingLeft()) ? ball.x - Ball.RADIUS : playWidth - ball.x + Ball.RADIUS;

    // Effective x-translation left over after first bounce
    float remains = (total - wallDist) % playWidth;

    // Bounces the ball will incur
    int bounces = (int) ((total) / playWidth);

    boolean left = (bounces % 2 == 0) ? !ball.goingLeft() : ball.goingLeft();

    cpu.destination = getWidth() / 2;

    // Now we need to compute the final x. That's all that matters.
    if (bounces == 0) {
      cpu.destination = (int) (ball.x + total * Math.signum(ball.vx));
    } else if (left) {
      cpu.destination = (int) (Ball.RADIUS + remains);
    } else { // The ball is going right...
      cpu.destination = (int) ((Ball.RADIUS + playWidth) - remains);
    }

    // Try to give it a little kick if vx = 0
    int salt = (int) (System.currentTimeMillis() / 10000);
    Random r = new Random((long) (cpu.centerY() + ball.vx + ball.vy + salt));
    int width = cpu.getWidth();
    cpu.destination =
        (int)
            bound(
                cpu.destination + r.nextInt(2 * width - (width / 5)) - width + (width / 10),
                0,
                getWidth());
    cpu.move(true);
  }