@Override public boolean onTrackballEvent(MotionEvent event) { if (!gameRunning()) return false; if (mBlue.player == false) { mBlue.player = true; mBlue.destination = mBlue.centerX(); } switch (event.getAction()) { case MotionEvent.ACTION_MOVE: mBlue.destination = (int) Math.max( 0, Math.min(getWidth(), mBlue.destination + SCROLL_SENSITIVITY * event.getX())); break; } return true; }
/** Resets the lives and the position of the paddles. */ private void resetPaddles() { int mid = getWidth() / 2; mRed.setPosition(mid); mBlue.setPosition(mid); mGreen.setPosition(mid); mYellow.setPosition(mid); mCyan.setPosition(mid); mOrange.setPosition(mid); mRed.destination = mid; mBlue.destination = mid; mGreen.destination = mid; mYellow.destination = mid; mCyan.destination = mid; mOrange.destination = mid; mRed.setLives(STARTING_LIVES); mBlue.setLives(STARTING_LIVES); }
/** * Touching is the method of movement. Touching the touchscreen, that is. A player can join in * simply by touching where they would in a normal game. */ public boolean onTouch(View v, MotionEvent mo) { if (v != this || !gameRunning()) return false; // We want to support multiple touch and single touch InputHandler handle = InputHandler.getInstance(); // Loop through all the pointers that we detected and // process them as normal touch events. for (int i = 0; i < handle.getTouchCount(mo); i++) { int tx = (int) handle.getX(mo, i); int ty = (int) handle.getY(mo, i); // Bottom paddle moves when we are playing in one or two player mode and the touch // was in the lower quartile of the screen. if (mBlue.player && mBlue.inTouchbox(tx, ty)) { mBlue.destination = tx; mGreen.destination = tx; mCyan.destination = tx; } else if (mRed.player && mRed.inTouchbox(tx, ty)) { mRed.destination = tx; mYellow.destination = tx; mOrange.destination = tx; } else if (mo.getAction() == MotionEvent.ACTION_DOWN && mPauseTouchBox.contains(tx, ty)) { if (mCurrentState != State.Stopped) { mLastState = mCurrentState; mCurrentState = State.Stopped; } else { mCurrentState = mLastState; mLastState = State.Stopped; } } // In case a player wants to join in... if (mo.getAction() == MotionEvent.ACTION_DOWN) { if (!mBlue.player && mBlue.inTouchbox(tx, ty)) { mBlue.player = true; } else if (!mRed.player && mRed.inTouchbox(tx, ty)) { mRed.player = true; } } } return true; }
private void aiFollow(Paddle cpu) { cpu.destination = (int) mBall.x; cpu.move(true); }
private void aiExact(Paddle cpu) { cpu.destination = (int) mBall.x; cpu.setPosition(cpu.destination); }
/** * 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); }