package pr1; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.util.Random; import javax.swing.JPanel; @SuppressWarnings("serial") public class SemiPongPanel extends JPanel implements BallHandler, MouseMotionListener { private static Random rand = new Random(); private final int STRING_X = 10; private final int STRING_Y = 15; private final int STRING_DELTA_Y = 15; private final int STRING_BOTTOM_PAD = 5; private final int NUM_BALLS = 20; private final int BALL_X = 50; private final int BALL_Y = 100; private final int BALL_RADIUS = 10; private final int SECONDS_PER_BALL = 2; private final int FRAMES_PER_SECOND = 10; private final int MIN_X_VELOCITY = 10; private final int MAX_X_VELOCITY = 100; private final int MIN_Y_VELOCITY = -100; private final int MAX_Y_VELOCITY = 100; private final int PADDLE_X_INIT = 300; private final int PADDLE_TOP_INIT = 50; private final int PADDLE_LENGTH_INIT = 50; private final Color BACKGROUND_COLOR = Color.lightGray; private final Color BALL_COLOR = Color.red; private Ball[] balls; private int ballsFired = 0; private int ballsToLeft = 0; private int ballsToRight = 0; private int collisionCount = 0; private BallPhysics physics; private int paddleTop = PADDLE_TOP_INIT; private int paddleLength = PADDLE_LENGTH_INIT; private int paddleX = PADDLE_X_INIT; private int tickCounter = 0; public SemiPongPanel(int w, int h) { setPreferredSize(new Dimension(w, h)); physics = new BallPhysics(this, this, FRAMES_PER_SECOND); balls = new Ball[NUM_BALLS]; for (int i = 0; i < balls.length; i++) { balls[i] = new Ball(BALL_X, BALL_Y, BALL_RADIUS, randomRange(MIN_X_VELOCITY, MAX_X_VELOCITY), randomRange(MIN_Y_VELOCITY, MAX_Y_VELOCITY), BALL_COLOR); } physics.setBallHandler(this); addMouseMotionListener(this); } public void paintComponent(Graphics g) { Rectangle bounds = getBounds(); g.setColor(BACKGROUND_COLOR); g.fillRect(0, 0, bounds.width, bounds.height); g.setColor(Color.black); g.drawString("Semi-Pong Part 6 by S. Robbins", STRING_X, STRING_Y); g.drawString("Balls Remaiing: " + (balls.length - ballsFired), STRING_X, STRING_Y + STRING_DELTA_Y); g.drawString("Balls To Left: " + ballsToLeft, STRING_X, STRING_Y + 2 * STRING_DELTA_Y); g.drawString("Balls To Right: " + ballsToRight, STRING_X, STRING_Y + 3 * STRING_DELTA_Y); g.drawString("Collisions: " + collisionCount, STRING_X, STRING_Y + 4 * STRING_DELTA_Y); if (balls.length == ballsToLeft + ballsToRight) g.setColor(Color.red); g.drawString("Score: " + (2*ballsToLeft - ballsToRight + collisionCount), STRING_X, bounds.height - STRING_BOTTOM_PAD); g.setColor(BALL_COLOR); g.drawOval(BALL_X-BALL_RADIUS,BALL_Y-BALL_RADIUS,2*BALL_RADIUS,2*BALL_RADIUS); for (int i = 0; i < ballsFired; i++) balls[i].draw(g); g.setColor(Color.black); g.drawLine(paddleX, paddleTop, paddleX, paddleTop + paddleLength); } private static double randomRange(double low, double high) { return low + (high - low) * rand.nextDouble(); } @Override public void collided(Ball b1, Ball b2) { collisionCount++; } @Override public void handleBall(Ball b) { double x = b.getX(); double r = b.getRadius(); double vx = b.getVelocityX(); double y = b.getY(); if ((x+r < paddleX) || (x-r > paddleX)) return; if ((y+r < paddleTop) || (y-r > paddleTop+paddleLength)) return; if (vx < 0) return; b.setVelocityX(-vx); b.setX(2*(paddleX-r)-x); } @Override public void handleTick() { tickCounter++; if (tickCounter % SECONDS_PER_BALL != 0) return; if (ballsFired < balls.length) { physics.addBall(balls[ballsFired]); ballsFired++; } } @Override public void hitLeftWall(Ball b) { ballsToLeft++; hideBall(b); } @Override public void hitRightWall(Ball b) { ballsToRight++; hideBall(b); } private void hideBall(Ball b) { b.setVelocityX(0); b.setVelocityY(0); b.setX(-b.getRadius()-1); } @Override public void mouseDragged(MouseEvent e) { } @Override public void mouseMoved(MouseEvent e) { int height = getBounds().height; int newPaddleTop = e.getY() - paddleLength; if (newPaddleTop < 0) newPaddleTop = 0; if (newPaddleTop + paddleLength > height) newPaddleTop = height - paddleTop; paddleTop = newPaddleTop; } }