Midterm Project: Brick Breaker Game – Help the Wolf Break the House

Concept and Guide of the Game

The original story of three little pigs ends with the wolf failing to break into the brick house. The concept of my game is the opposite of this. The aim of the game is to help the wolf break the brick wall of the house and encounter the pigs. I wanted to give a twist to the original story and help the wolf win over the three little pigs. 

The game follows the same rules of the brick breaker game. But the idea is to break all the bricks using the bouncing ball so that the wolf can meet up with the pigs. Playing the game is simple. When the user clicks on the start button on the opening page, the game starts immediately. The user must use the mouse to move the paddle to bounce off the balls and break the bricks. Simultaneously, a timer runs to measure the time it takes the user to break all the bricks. The aim of this game is to break all the bricks in the shortest time possible. The timer is displayed throughout the game at the bottom left corner and the final time is displayed at the ending page that appears when the bricks are all gone. The user can replay the game by simply clicking on the replay button that navigates the user back to the opening page. 

Understanding the Overall Code

I created three classes for the game: ball, paddle, and brick. 

First, in the class Ball, I have three smaller functions: draw, move, and bounce. The functions instruct the ball to be drawn on the canvas, to animate across the canvas, and to change directions. 

Second, in the class Paddle, I drew the paddle and made it so that the ball bounces off the paddle when in contact. 

Lastly, in the class Brick, I drew the brick and used ‘if and else’ to detect the four edges of the brick. Also, I used ‘if and else’ to test if the ball and the brick collided. 

With these three classes, I called them in the main sketch and operated the game. In the main sketch, there are 9 other functions: preload, setup, startGame, draw, drawStartPage, allBricksGone, endGame, replayGame, and createTimer. There are specific instructions under each function that controls the behavior of the game. 

What I am Proud Of 

The first part of the code that I am proud of is the function for the timer. At first, I had no timer and hence the goal of the game was to simply break all the bricks. However, I realized that if there is no timer, the user is not put under any pressure to play the game well. Therefore, I decided to place a timer so that the user is pushed to play and finish the game faster. 

function createTimer() {
  //timer object with update and display methods
  let timerObject = {
    startTime: 0,
    elapsed: 0,

    update: function () {
      this.elapsed = millis() - this.startTime;
    },

    display: function () {
      textSize(13);
      textAlign(CENTER, CENTER);
      fill('black');
      stroke('white');
      textFont('Verdana');
      text('Time: ' + this.format(), width / 2 - 150, height - 10);
    },

    format: function () {
      //convert milliseconds to a readable time format (mm:ss)
      let minutes = Math.floor(this.elapsed / 60000);
      let seconds = ((this.elapsed % 60000) / 1000).toFixed(1);
      return minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
    },
  };

  return timerObject;
}

Another part of the code that I am proud of is the function for endGame. Under this function, I created a button that allows the user to replay the game. So when the endButton, which is the button used to replay the game, is pressed, the function for replayGame is operated. When the endGame function runs, the time it took the user to finish the game is displayed for the user. 

function endGame() {
  //show the end page with replay button
  background(255);

  push();
  translate(10, 50);
  scale(0.4);
  image(startImg, 0, 0);
  pop();

  //create a replay button
  endButton.show();
  endButton.position(width / 2 - endButton.width / 2, height / 2);
  
  textSize(30);
  textAlign(CENTER, CENTER);
  fill(0);
  textFont(myFont);
  text('You destroyed the house!', width / 2, height / 4 - 70);
  textSize(16);
  text('Click "Replay" to play again.', width / 2, height / 2 - 140);
  
  endButton.mousePressed(replayGame);

  //display the final time
  textSize(16);
  text('Your Time: ' + timer.format(), width / 2, height / 2 - 100);
}

Also, I am very pleased with the look of the game. The theme or the design fits well into the concept of the game and adds to the experience of the user. The picture below is the the initial design of the game. From that design, I added colors and images to add aesthetics.

Difficulty & How I Overcame It 

The hardest part of coding was using the ‘if and else’ statement to change the pages of the game (opening, game, and ending). As shown below, the code itself is simple: I just have to call the classes and functions that I created previously and use the ‘if and else’ statement to create conditions. However, for some reason I could not navigate from one page to another. Through trial and error, I was able to get it to work. 

function draw() {
  //draw the start page if the game hasn't started or if it's replaying
  if ((!ball || allBricksGone())&& start== true ) {
    drawStartPage();
  } else {
    //draw the game elements
    push();
    translate(-15, 0);
    scale(0.34);
    image(backgroundImg, 0, 0);
    pop();

    paddle.x = mouseX;

    //nested loop for creating bricks when not collided with the ball
    for (let i = 0; i < cols; i++) {
      for (let j = 0; j < rows; j++) {
        if (bricks[i][j].val == 0) {
          bricks[i][j].drawBrick();
          bricks[i][j].collided(ball);
        }
      }
    }

    //check if all bricks are gone
    if (allBricksGone()) {
      endGame();
    } else {
      //update the timer
      timer.update();

      ball.moveBall();
      ball.bounceBall();
      ball.drawBall();

      paddle.hitPaddle(ball);
      paddle.drawPaddle();

      //display the timer
      timer.display();
    }
  }
}

These are the pages in the order of opening, game, and ending.

Improvement

For improvement, I would like to enable fullscreen. As of now, the game screen is too small and the game experience would be enhanced when the game screen is larger. 

Another improvement I would like to make is displaying the record of the 5 fastest times on the ending page. In this way, the user would be more motivated to play better and faster.

Lastly, it would be more entertaining if I create a losing condition. For instance, I could make the ball not bounce off the bottom wall so that when the ball passes through the bottom wall, the time increases by 3 seconds. In this way, it would take longer and be harder for the user to complete the game.

Leave a Reply