package breakout; import java.awt.geom.*; import java.awt.*; import fang.*; /** * This class implements the game of Breakout. * * @author Robert C. Duvall * @author modified by Joseph Farfel (updated for the * FANG engine, and some other changes) */ public class Breakout extends GameLoop { // Game objects /** the walls */ private Sprite[] walls; /** the blocks */ // Makes an array of blocks private Sprite[] block; /** the paddle */ private Sprite paddle; /** the bouncing ball */ private Sprite ball; //Integer for score public static int score = 0; //Integer for lives public static int lives = 3; //StringSprite for score private StringSprite scoreSprite; //StringSprite for lives private StringSprite livesSprite; /** what makes the ball move */ private ProjectileTracker ballTracker; // Game resources (sounds, etc.) // TODO: add variables to store two sounds (Sound) /** * This is the Breakout class's constructor method. It is * called once, when the program starts. */ public Breakout() { // set the size of the game window (in pixels) super(new Dimension(500, 500)); // tell the game where its help file is setHelp("resources/BreakoutHelp.html"); } /** * This method is run every time the game is restarted. It * creates and sets up all Sprites, and initializes all game * state variables (score, lives, etc.). */ public void startGame() { // TODO: initialize game state variables and sounds makeSprites(); addSprites(); } /** * One step in the game. * * Updates position of paddles based on players and * handles any collisions with the ball. * * @see tipgame.FrameAdvancer#advanceFrame() */ public void advanceFrame (double timePassed) { if (! this.gameIsOver()) { handleInput(); handleCollisions(); updateStatus(); } } /** * Creates all of the sprites and sets up their location, * scale, and color */ private void makeSprites () { // make the walls array walls = new Sprite[4]; // make each individual wall walls[0] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.1)); walls[1] = new Sprite(new Rectangle2D.Double(0, 0, 0.1, 1)); walls[2] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.1)); walls[3] = new Sprite(new Rectangle2D.Double(0, 0, 0.1, 1)); // set up the walls' color, scale, location for (Sprite wall : walls) { wall.setScale(1); wall.setColor(new Color(0, 30, 150)); } walls[0].setLocation(0.5, 0); walls[1].setLocation(0, 0.5); walls[2].setLocation(0.5, 1); walls[3].setLocation(1, 0.5); // TODO: create and set up lots of blocks //make the block array block = new Sprite[15]; // make the blocks block[0] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.5)); block[1] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.5)); block[2] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.5)); block[3] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.5)); block[4] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.5)); block[5] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.5)); block[6] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.5)); block[7] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.5)); block[8] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.5)); block[9] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.5)); block[10] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.5)); block[11] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.5)); block[12] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.5)); block[13] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.5)); block[14] = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.5)); for(Sprite blocks : block) { blocks.setScale(0.15); blocks.setColor(Color.MAGENTA); } // set up the blocks' color, scale, location block[0].setLocation(0.5, 0.25); block[1].setLocation(0.33, 0.25); block[2].setLocation(0.161, 0.25); block[3].setLocation(0.67, 0.25); block[4].setLocation(0.84, 0.25); block[5].setLocation(0.5, 0.15); block[6].setLocation(0.33, 0.15); block[7].setLocation(0.161, 0.15); block[8].setLocation(0.67, 0.15); block[9].setLocation(0.84, 0.15); block[10].setLocation(0.5, 0.35); block[11].setLocation(0.33, 0.35); block[12].setLocation(0.161, 0.35); block[13].setLocation(0.67, 0.35); block[14].setLocation(0.84, 0.35); // make the paddle paddle = new Sprite(new Rectangle2D.Double(0, 0, 1, 0.1)); // set up the paddle's color, scale, location paddle.setColor(Color.GREEN); paddle.setScale(0.2); paddle.setLocation(0.5, 0.9); //Make and Setup the score sprite scoreSprite = new StringSprite("Blocks left: "+score); scoreSprite.rightJustify(); scoreSprite.topJustify(); scoreSprite.setHeight(0.05); scoreSprite.setLocation(1, 0); scoreSprite.setColor(Color.BLACK); //Make and Setup the lives sprite livesSprite = new StringSprite("Lives left: "+lives); livesSprite.leftJustify(); livesSprite.topJustify(); livesSprite.setHeight(0.05); livesSprite.setLocation(0, 0); livesSprite.setColor(Color.BLACK); // make the ball ball = new Sprite(new Ellipse2D.Double(0, 0, 1, 1)); // set up the ball's color, scale, location ball.setColor(Color.RED); ball.setScale(0.05); ball.setLocation(0.5, 0.5); // make the ball's tracker and assign it to the ball ballTracker = new ProjectileTracker(new Point2D.Double(0.2, 0.36)); ball.setTracker(ballTracker); } /** * Adds all the sprites to the canvas */ private void addSprites () { // add the walls (below everything else) for (Sprite current : walls) { canvas.addSprite(current); } for(Sprite current : block) { canvas.addSprite(current); } // TODO: add more blocks //canvas.addSprite(block); // Add the game indicators canvas.addSprite(scoreSprite); canvas.addSprite(livesSprite); // add the paddle canvas.addSprite(paddle); // add the ball (always on top of everything else) canvas.addSprite(ball); } /** * Uses the mouse to reposition the paddle. Also, we start a new * game if the user presses 'n' (or 'N'). */ private void handleInput () { // move one paddle using this computer's mouse Point2D.Double mouse = getPlayer().getMouse().getLocation(); paddle.setLocation(mouse.x, paddle.getLocation().y); // start a new game if the player presses 'n' if (getPlayer().getKeyboard().keyPressed()) { char in = getPlayer().getKeyboard().getLastKey(); if (in == 'n' || in == 'N') { startOver(); // restarts the entire game } } } /** * Checks for collisions between the ball and the four walls, the blocks, * and the paddle. If there is an intersection, the ball bounces off what * it hit (with the exception of the bottom wall, where a life is lost and the * ball's position is reset to the center of the screen). If the ball bounces * off of a brick, the brick disappears and points are earned. */ private void handleCollisions () { // check ball's position against each wall for (Sprite current : walls) { if (current.intersects(ball)) { ballTracker.bounce(ball, current); } } int i; for(i = 0; i==2; i++); { if(walls[i].intersects(ball)) { ballTracker.bounce(ball, walls[i]); } else { } } // TODO: check specially for floor intersection and update lives // check ball's position against the blocks // TODO: add more blocks and update score for (Sprite current : block) { if (current.isVisible() && current.intersects(ball)) { ballTracker.bounce(ball, current); current.setVisible(false); } } // check ball's position against the paddle if (paddle.intersects(ball)) { ballTracker.bounce(ball, paddle); } } /** * Updates the values of the game indicators to show the * player their score and remaining lives. */ private void updateStatus () { // TODO: update game status messages } /** * The start of the program. */ public static void main (String[] argv) { Breakout game = new Breakout(); game.runAsApplication(); } }