import java.applet.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class Breakout extends Applet implements Runnable, KeyListener, MouseListener, MouseMotionListener
{
private AnimatedShape paddle;
private AnimatedShape ball;
ArrayList list = new ArrayList<AnimatedShape>();
private Thread breakoutAnimator;
private int delay = 15;
private int rows = 2;
private static int columns = 7;
private boolean hit;
private boolean gameOver = false;
private boolean gameWon = false;
private boolean onMenu = true;
private boolean paused = false;
private Random gen = new Random();
public static final int BALL_DIAMETER = 15;
public static final int PADDLE_WIDTH = 60;
public static final int PADDLE_HEIGHT = 10;
public static final int BRICK_WIDTH = 60;
public static final int BRICK_HEIGHT = 20;
public static final int BUTTON_WIDTH = 80;
public static final int BUTTON_HEIGHT = 40;
private Rectangle2D.Double easy;
private Rectangle2D.Double medium;
private Rectangle2D.Double hard;
private int lives;
public void init()
{
easy = new Rectangle2D.Double(this.getWidth() / 2 - BUTTON_WIDTH / 2, this.getHeight() / 2 - BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT);
medium = new Rectangle2D.Double(this.getWidth() / 2 - BUTTON_WIDTH / 2, this.getHeight() / 2, BUTTON_WIDTH, BUTTON_HEIGHT);
hard = new Rectangle2D.Double(this.getWidth() / 2 - BUTTON_WIDTH / 2, this.getHeight() / 2 + BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT);
paddle = new AnimatedShape(new Rectangle2D.Double(2 * PADDLE_WIDTH, this.getHeight() / 2, PADDLE_WIDTH, PADDLE_HEIGHT),
this.getWidth() / 2, this.getHeight() - PADDLE_HEIGHT - 5, PADDLE_WIDTH, PADDLE_HEIGHT, 1, 0, 1, 5, Color.BLACK, Color.GREEN);
ball = new AnimatedShape(new Ellipse2D.Double(this.getHeight() / 2 - BALL_DIAMETER / 2, this.getHeight() / 2 - BALL_DIAMETER / 2,
BALL_DIAMETER, BALL_DIAMETER), this.getWidth() / 2 - BALL_DIAMETER / 2, this.getHeight() / 2 - BALL_DIAMETER / 2, BALL_DIAMETER,
BALL_DIAMETER, 1, 1, 3, 2, Color.BLACK, Color.RED);
list.clear();
for (int i = 0; i < columns; i++)
{
for (int j = 0; j < rows; j++)
{
AnimatedShape temp = new AnimatedShape(new Rectangle2D.Double(2 * BRICK_WIDTH, this.getHeight() / 2, BRICK_WIDTH, BRICK_HEIGHT),
((i * 3) + i * BRICK_WIDTH) + 30, ((j * 3) + j * BRICK_HEIGHT) + 6, BRICK_WIDTH, BRICK_HEIGHT, 0, 1, 1, 5, Color.BLACK,
Color.GREEN);
list.add(temp);
}
}
this.setFocusable(true);
this.addKeyListener(this);
this.addMouseMotionListener(this);
this.addMouseListener(this);
lives = 3;
hit = false;
// onMenu = true;
gameOver = false;
gameWon = false;
}
public void start()
{
breakoutAnimator = new Thread(this);
breakoutAnimator.start();
}
// This method is called with the Applet is closed.
public void stop()
{
breakoutAnimator = null;
}
// The paint method.
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
// recover Graphics2D
if (onMenu)
{
g2.setColor(Color.GREEN);
g2.fill(easy);
g2.setColor(Color.ORANGE);
g2.fill(medium);
g2.setColor(Color.RED);
g2.fill(hard);
g2.setColor(Color.BLACK);
g2.setFont(new Font("Helvetica", Font.BOLD, 20));
g2.drawString("EASY", (int) easy.getX(), (int) easy.getY() + BUTTON_HEIGHT);
g2.drawString("MEDIUM", (int) medium.getX(), (int) medium.getY() + BUTTON_HEIGHT);
g2.drawString("HARD", (int) hard.getX(), (int) hard.getY() + BUTTON_HEIGHT);
}
else if (!gameOver)
{
g2.setColor(Color.BLACK);
g2.setColor(paddle.getFillColor());
g2.fill(paddle.getShape());
for (int i = 0; i < list.size(); i++)
{
g2.setColor(new Color(gen.nextInt(256), gen.nextInt(256), gen.nextInt(256)));
g2.fill(((AnimatedShape) list.get(i)).getShape());
}
g2.setColor(ball.getFillColor());
g2.fill(ball.getShape());
g2.setColor(Color.BLACK);
g2.setFont(new Font("Helvetica", Font.BOLD, 20));
g2.drawString(Integer.toString(lives), 10, 20);
if (paused)
{
g2.setColor(new Color(100, 100, 100, 100));
g2.fillRect(0, 0, this.getWidth(), this.getHeight());
g2.setColor(new Color(0, 0, 0, 100));
g2.fillRoundRect(this.getWidth() / 2 - 75, this.getHeight() / 2 - 110, 150, 200, 15, 15);
g2.setColor(new Color(0, 0, 0, 100));
g2.drawRoundRect(this.getWidth() / 2 - 75, this.getHeight() / 2 - 110, 150, 200, 15, 15);
g2.drawRoundRect(this.getWidth() / 2 - 74, this.getHeight() / 2 - 109, 148, 198, 15, 15);
g2.setColor(new Color(0, 0, 0, 100));
g2.fillRoundRect(this.getWidth() / 2 - 70, this.getHeight() / 2 - 25, 140, 50, 15, 15);
g2.setColor(new Color(255, 255, 255, 200));
g2.drawRoundRect(this.getWidth() / 2 - 70, this.getHeight() / 2 - 25, 140, 50, 15, 15);
g2.setColor(new Color(0, 0, 0, 100));
g2.fillRoundRect(this.getWidth() / 2 - 70, this.getHeight() / 2 - 80, 140, 50, 15, 15);
g2.setColor(new Color(255, 255, 255, 200));
g2.drawRoundRect(this.getWidth() / 2 - 70, this.getHeight() / 2 - 80, 140, 50, 15, 15);
g2.setColor(new Color(0, 0, 0, 100));
g2.fillRoundRect(this.getWidth() / 2 - 70, this.getHeight() / 2 + 30, 140, 50, 15, 15);
g2.setColor(new Color(255, 255, 255, 200));
g2.drawRoundRect(this.getWidth() / 2 - 70, this.getHeight() / 2 + 30, 140, 50, 15, 15);
g2.setFont(new Font("Helvetica", Font.BOLD, 20));
g2.drawString("Main Menu", this.getWidth() / 2 - 53, this.getHeight() / 2 - 88);
g2.drawString("EASY", this.getWidth() / 2 - 27, this.getHeight() / 2 - 50);
g2.drawString("MEDIUM", this.getWidth() / 2 - 39, this.getHeight() / 2 + 7);
g2.drawString("HARD", this.getWidth() / 2 - 27, this.getHeight() / 2 + 63);
}
}
else
{
if (gameWon)
{
g2.setColor(Color.BLACK);
g2.setFont(new Font("Helvetica", Font.BOLD, 20));
g2.drawString("Congratulations", this.getWidth() / 2 - 60, this.getWidth() / 2 - 5);
}
else
{
g2.setColor(Color.BLACK);
g2.setFont(new Font("Helvetica", Font.BOLD, 20));
g2.drawString("Game Over", this.getWidth() / 2 - 50, this.getWidth() / 2 - 5);
}
}
}
// After the start method has been called, the run method is called.
public void run()
{
// Check that the current thread is still our pongAnimator.
while (Thread.currentThread() == breakoutAnimator)
{
do
{
if (!paused)
{
System.out.println(paused);
/******************************************************
* CODE TO BE ADDED BY YOU
*****************************************************/
// System.out.println("##########################");
// System.out.println(paddle.toString() + "\n" +
// ball.toString());
// if ball is within the y of the paddle
// System.out.println(lives + ", " + list.size());
if (ball.getBottomLeftPoint().getY() >= paddle.getTopLeftPoint().getY()
&& ball.getBottomLeftPoint().getY() <= paddle.getBottomLeftPoint().getY())
{
if (ball.getBottomRightPoint().getX() > paddle.getTopLeftPoint().getX()
&& ball.getBottomLeftPoint().getX() < paddle.getTopRightPoint().getX())
{
ball.setY((int) paddle.getTopRightPoint().getY() - BALL_DIAMETER + 1);
ball.changeVerticalDirection();
}// end if
}// end if
// if ball hits sides of screen
if (ball.getTopLeftPoint().getX() <= 0 || ball.getTopRightPoint().getX() >= this.getWidth())
ball.changeHorizontalDirection();
// if ball hits top of screen
if (ball.getTopLeftPoint().getY() <= 0)
ball.changeVerticalDirection();
// if the ball reaches the bottom
if (ball.getTopLeftPoint().getY() > this.getHeight())
{
lives--;
if (lives == 0)
gameOver = true;
ball.setX(this.getWidth() / 2 - BALL_DIAMETER / 2);
ball.setY(this.getHeight() / 2 - BALL_DIAMETER / 2);
}
for (int i = 0; i < list.size(); i++)
{
hit = false;
if (((AnimatedShape) list.get(i)).getShape().contains(ball.getLeftSide())
|| ((AnimatedShape) list.get(i)).getShape().contains(ball.getRightSide()))
{
ball.changeHorizontalDirection();
hit = true;
}
if (((AnimatedShape) list.get(i)).getShape().contains(ball.getTopSide())
|| ((AnimatedShape) list.get(i)).getShape().contains(ball.getBottomSide()))
{
ball.changeVerticalDirection();
hit = true;
}
if (hit)
{
list.remove(i);
hit = false;
}
}
// test to see if game is won
if (list.size() == 0)
{
gameWon = true;
gameOver = true;
}
ball.moveShape();
repaint();
// Have the Thread sleep for 1 second at a time.
try
{
Thread.sleep(delay);
}
catch (InterruptedException e)
{
break;
}
}
}
while (!onMenu);
}
}
// The following methods control the keyboard input.
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_SPACE)
{
onMenu = true;
init();
}
if (e.getKeyCode() == KeyEvent.VK_UP)
{
if (delay > 0)
delay--;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN)
{
delay++;
}
if (e.getKeyCode() == KeyEvent.VK_P)
{
if (paused)
{
paused = false;
}
else
{
paused = true;
repaint();
}
}
if (e.getKeyCode() == KeyEvent.VK_R)
{
repaint();
}
}
public void keyReleased(KeyEvent e)
{}
public void keyTyped(KeyEvent e)
{}
public void mouseMoved(MouseEvent e)
{
if (!paused)
{
int mouseX = e.getX() - PADDLE_WIDTH / 2;
paddle.setX(mouseX);
paddle.moveShape();
repaint();
}
}
public void mouseDragged(MouseEvent e)
{
Point2D.Double mouse = new Point2D.Double(e.getX(), e.getY());
for (int i = 0; i < list.size(); i++)
{
hit = false;
if (((AnimatedShape) list.get(i)).getShape().contains(mouse))
{
list.remove(i);
}
}
}
public void mousePressed(MouseEvent e)
{}
public void mouseClicked(MouseEvent e)
{
Point2D.Double mouse = new Point2D.Double(e.getX(), e.getY());
if (onMenu)
{
if (easy.contains(mouse))
{
delay = 15;
rows = 2;
onMenu = false;
}
else if (medium.contains(mouse))
{
delay = 10;
rows = 5;
onMenu = false;
}
else if (hard.contains(mouse))
{
delay = 5;
rows = 10;
onMenu = false;
}
init();
}
if(paused)
{
if(new RoundRectangle2D.Double(this.getWidth() / 2 - 70, this.getHeight() / 2 - 25, 140, 50, 15, 15).contains(mouse))
{
delay = 10;
rows = 5;
paused = false;
}
else if(new RoundRectangle2D.Double(this.getWidth() / 2 - 70, this.getHeight() / 2 - 80, 140, 50, 15, 15).contains(mouse))
{
delay = 15;
rows = 2;
paused = false;
}
else if(new RoundRectangle2D.Double(this.getWidth() / 2 - 70, this.getHeight() / 2 + 30, 140, 50, 15, 15).contains(mouse))
{
delay = 5;
rows = 10;
paused = false;
}
repaint();
init();
}
}
public void mouseReleased(MouseEvent e)
{}
public void mouseEntered(MouseEvent e)
{}
public void mouseExited(MouseEvent e)
{}
}