Breakout!
Salvador Briseno and Marco Bermudez
Code
/* @pjs preload="data/doubleP.png,data/unnamed.png",data/merry.jpg; */
/**
* FALL 2018 SEMESTER FINAL PROJECT - BREAKOUT
* TEAM:
* DATE:
*/
public final int BALL_RADIUS = 8;
public final int BALL_DIAMETER = BALL_RADIUS * 2;
public final int PADDLE_WIDTH = 100;
public final int PADDLE_HEIGHT = 10;
public final int SHRINK_PADDLE_WIDTH = 50;
public final int BRICK_WIDTH = 44;
public final int BRICK_HEIGHT = 20;
private final int RED_NUMBERS_HITS = 3;
private int[]redBricksHits = new int[10];
private Ball ball;
public Brick[] redBricks = new Brick[10];
public Brick[] orangeBricks = new Brick[10];
public Brick[] yellowBricks = new Brick[10];
public Brick[] greenBricks = new Brick[10];
public Brick[] blueBricks = new Brick[10];
// TODO: put the rest of the rows here
public boolean hasGameStarted = false;
public boolean isGameOver = false;
public int paddleX;
public int paddleY;
public int lives = 3;
public int points = 0;
private PImage bg;
private SoundFile hitBrick;
private SoundFile hitWall;
private SoundFile pauseSong;
private SoundFile song;
private PImage doubleP;
private float dpx = -100;
private float dpy = 240;
private boolean isDoublePActive = false;
private float dpSpeedY = 1.0;
private int dpCounter = 0;
private PImage plusLive;
private float plx = -100;
private float ply = 240;
private float plSpeedY = 1.0;
private boolean isPaused = false;
public void setup()
{
size(480, 480);
//pixelDensity(2);
doubleP = loadImage("data/doubleP.png");
doubleP.resize(40, 0);
plusLive = loadImage("data/unnamed.png");
plusLive.resize(20, 0);
bg = loadImage("data/merry.jpg");
bg.resize(480, 480);
hitBrick = new SoundFile(this, "hit.wav");
hitWall = new SoundFile(this, "pipe.wav");
pauseSong = new SoundFile(this, "wiiMusic.mp3");
song = new SoundFile(this, "starWars.mp3");
// Initial ball position
ball = new Ball(width / 2, height - PADDLE_HEIGHT - BALL_RADIUS);
paddleX = width / 2 - PADDLE_WIDTH / 2;
paddleY = height - PADDLE_HEIGHT;
// TODO: create the red bricks
for (int i = 0; i < redBricks.length; i++)
{
Brick b = new Brick(48 * i + 2, 5, color(255, 0, 0));
redBricks[i] = b;
}
//TODO: create the oranges bricks
for (int i = 0; i < orangeBricks.length; i++)
{
Brick b = new Brick(48 * i + 2, 30, color(255, 215, 0));
orangeBricks[i] = b;
}
// TODO: create the yellow bricks
for (int i = 0; i < yellowBricks.length; i++)
{
Brick b = new Brick(48 * i + 2, 55, color(255, 255, 0));
yellowBricks[i] = b;
}
// TODO: create the green bricks
for (int i = 0; i < greenBricks.length; i++)
{
Brick b = new Brick(48 * i + 2, 80, color(34, 139, 34));
greenBricks[i] = b;
}
// TODO: create the blue bricks
for (int i = 0; i < blueBricks.length; i++)
{
Brick b = new Brick(48 * i + 2, 105, color(135, 206, 250));
blueBricks[i] = b;
}
}
public void draw()
{
if (!isGameOver)
{
background(bg);
// Draw the ball.
ball.drawBall();
image(plusLive, plx, ply);
image(doubleP, dpx, dpy);
if (blueBricksBroken())
{
dpy += dpSpeedY;
}
if (collideWithDP())
{
isDoublePActive = true;
ball.reverseSpeedX();
dpSpeedY = 0;
dpx = -100;
}
if (dpy > height)
{
dpy = -50;
dpx = random(0, width - 40);
}
if (ply > height)
{
ply = -50;
plx = random(0, width - 40);
}
if (greenBricksBroken())
{
ply += plSpeedY;
}
if (collideWithPL())
{
ball.reverseSpeedX();
plSpeedY = 0;
plx = -100;
lives++;
}
// Draw the paddle.
if (yellowBricksBroken())
{
fill(0);
rect(paddleX, paddleY, SHRINK_PADDLE_WIDTH, PADDLE_HEIGHT);
} else {
fill(0);
rect(paddleX, paddleY, PADDLE_WIDTH, PADDLE_HEIGHT);
}
// TODO: Lives & Points
fill(0);
textSize(25);
text("Lives: " + lives, 320, 479);
text("Points: " + points, 320, 460);
textSize(10);
text("Press P to Pause", 0, 479);
// TODO: check for wall collisions
if (didHitSide())
{
hitWall.play();
ball.reverseSpeedX();
}
if (isBallCollidingWithPaddle())
{
ball.reverseSpeedY();
}
if (isOutOfBounds())
{
paddleX = width / 2 - PADDLE_WIDTH / 2;
paddleY = height - PADDLE_HEIGHT;
ball.setSpeedX(0);
ball.setSpeedY(0);
ball.setX(width / 2);
ball.setY(height - PADDLE_HEIGHT - BALL_RADIUS);
lives--;
song.stop();
hasGameStarted = false;
}
// TODO: draw the bricks
for (int i = 0; i < redBricks.length; i++)
{
if (redBricks[i] != null)
{
Brick myBrick = redBricks[i];
myBrick.drawBrick();
}
}
for (int i = 0; i < orangeBricks.length; i++)
{
if (orangeBricks[i] != null)
{
Brick myBrick = orangeBricks[i];
myBrick.drawBrick();
}
}
for (int i = 0; i < yellowBricks.length; i++)
{
if (yellowBricks[i] != null)
{
Brick myBrick = yellowBricks[i];
myBrick.drawBrick();
}
}
for (int i = 0; i < greenBricks.length; i++)
{
if (greenBricks[i] != null)
{
Brick myBrick = greenBricks[i];
myBrick.drawBrick();
}
}
for (int i = 0; i < blueBricks.length; i++)
{
if (blueBricks[i] != null)
{
Brick myBrick = blueBricks[i];
myBrick.drawBrick();
}
}
if (lives <= 0)
{
lostAllLives();
}
if (isDoublePActive)
{
dpCounter++;
if (dpCounter > 800)
{
isDoublePActive = false;
dpCounter = 0;
}
}
// TODO: check for brick collisions
if (checkForCollisions())
{
hitBrick.play();
if (isDoublePActive)
{
points = points * 2;
} else {
points+= 2;
}
ball.reverseSpeedY();
}
if (areAllBricksBroken())
{
gameOver(true);
}
// TODO: check for paddle collision
if (didHitTop())
{
ball.reverseSpeedY();
}
}
}
public void keyReleased()
{
if (key == 'p')
{
isPaused = !isPaused;
if (isPaused)
{
textSize(35);
text("Pause", width/2 - 50, height/2 + 50);
noLoop();
pauseSong.play();
song.stop();
} else
{
pauseSong.stop();
song.play();
loop();
}
}
}
public void mouseMoved(MouseEvent event)
{
int x = mouseX;
paddleX = x - PADDLE_WIDTH / 2;
if (!hasGameStarted)
{
ball.setX(x);
ball.setY(height - PADDLE_HEIGHT - BALL_RADIUS);
}
}
public void mouseReleased(MouseEvent event)
{
if (!hasGameStarted)
{
song.play();
ball.setSpeedX(5);
ball.setSpeedY(-3);
hasGameStarted = true;
}
if (isGameOver)
{
restartGame();
}
}
/**
* Return true if the ball has hit the left or right sides.
*/
public boolean didHitSide()
{
// TODO
if (ball.getX() < 0 || ball.getX() > width)
{
return true;
}
return false;
}
/**
* Return true if the ball has hit the top side.
*/
public boolean didHitTop()
{
// TODO
if (ball.getY() < 0)
{
return true;
}
return false;
}
/**
* Return true with the ball passed through the bottom.
*/
public boolean isOutOfBounds()
{
if (ball.getY() > height)
{
return true;
}
// TODO
return false;
}
/**
* Return true when the ball is colliding with the paddle.
*/
public boolean isBallCollidingWithPaddle()
{
if (ball.getX() == paddleX && ball.getY() == paddleY) {
return true;
}
return isBallCollidingWithRect(paddleX, paddleY, PADDLE_WIDTH, PADDLE_HEIGHT);
}
/**
* Detects whether the ball is colliding with a brick.
* Use a loop to check every brick for collisions.
* If a brick has been hit, remove it and return true.
* If not bricks are being hit, return false.
*/
public boolean checkForCollisions()
{
for (int i = 0; i < redBricks.length; i++)
{
if (redBricks[i] != null)
{
Brick myBrick = redBricks[i];
if (myBrick.isCollidingWithBall())
{
redBricksHits[i]++;
myBrick.setColor(color(255, random(0,50), random(0,50)));
if(redBricksHits[i] == RED_NUMBERS_HITS)
{
redBricks[i] = null;
}
return true;
}
}
}
for (int i = 0; i < orangeBricks.length; i++)
{
if (orangeBricks[i] != null)
{
Brick myBrick = orangeBricks[i];
if (myBrick.isCollidingWithBall())
{
orangeBricks[i] = null;
return true;
}
}
}
for (int i = 0; i < yellowBricks.length; i++)
{
if (yellowBricks[i] != null)
{
Brick myBrick = yellowBricks[i];
if (myBrick.isCollidingWithBall())
{
yellowBricks[i] = null;
return true;
}
}
}
for (int i = 0; i < greenBricks.length; i++)
{
if (greenBricks[i] != null)
{
Brick myBrick = greenBricks[i];
if (myBrick.isCollidingWithBall())
{
greenBricks[i] = null;
return true;
}
}
}
for (int i = 0; i < blueBricks.length; i++)
{
if (blueBricks[i] != null)
{
Brick myBrick = blueBricks[i];
if (myBrick.isCollidingWithBall())
{
blueBricks[i] = null;
return true;
}
}
}
// TODO
return false;
}
/**
* Loops over every brick. If an unbroken brick is found, true false.
* If every brick has been broken, return true.
*/
public boolean areAllBricksBroken()
{
for (int i = 0; i < redBricks.length; i++)
{
if (redBricks[i] != null)
{
return false;
}
}
for (int i = 0; i < orangeBricks.length; i++)
{
if (orangeBricks[i] != null)
{
return false;
}
}
for (int i = 0; i < yellowBricks.length; i++)
{
if (yellowBricks[i] != null)
{
return false;
}
}
for (int i = 0; i < greenBricks.length; i++)
{
if (greenBricks[i] != null)
{
return false;
}
}
for (int i = 0; i < blueBricks.length; i++)
{
if (blueBricks[i] != null)
{
return false;
}
}
return true;
}
/**
* Ends the game.
* If param `didWin` is true, congratulate the use, else boo them.
* Prompt the user to click to restart the game.
* Ensure that the text is centered on the screen.
* Remember to set `isGameOver` to true.
*/
public void gameOver(boolean didWin)
{
isGameOver = true;
fill(255);
background(0);
textSize(50);
textAlign(CENTER);
text("You Win!", width/2, height/2);
// TODO
}
/**
* Restarts the game by reseting all of the instance variables.
*/
public void restartGame()
{
hasGameStarted = false;
isGameOver = false;
lives = 3;
points = 0;
plx = -100;
ply = 240;
dpx = -100;
dpy = 240;
isDoublePActive = false;
dpCounter = 0;
plx = -100;
ply = 240;
plSpeedY = 1.0;
setup();
// TODO
}
public void lostAllLives()
{
background(0);
fill(255);
textSize(50);
text("GAMEOVER", 150, width/2);
isGameOver = true;
}
public boolean blueBricksBroken()
{
for (int i = 0; i < blueBricks.length; i++)
{
if (blueBricks[i] != null)
{
return false;
}
}
return true;
}
public boolean collideWithDP()
{
if (ball.getX() == dpx && ball.getY() == dpy) {
return true;
}
return isBallCollidingWithRect(dpx, dpy, doubleP.width, doubleP.height);
}
public boolean greenBricksBroken()
{
for (int i = 0; i < greenBricks.length; i++)
{
if (greenBricks[i] != null)
{
return false;
}
}
return true;
}
public boolean collideWithPL()
{
if (ball.getX() == plx && ball.getY() == ply) {
return true;
}
return isBallCollidingWithRect(plx, ply, doubleP.width, doubleP.height);
}
public boolean yellowBricksBroken()
{
for (int i = 0; i < yellowBricks.length; i++)
{
if (yellowBricks[i] != null)
{
return false;
}
}
return true;
}