Stanford CS106A Breakout Game Setting Up Bricks Solution

So the first part of the Breakout game in Assignment 3 is setting up the bricks, as described in the instructions:

Here is my solution:

The hardest part about setting up the bricks for me was figuring out how to make sure the bricks were spaced out as they are in the picture. Otherwise, this was pretty similar to the Pyramid Problem in Assignment 2. Here is how I conquered this part, also available on gist.

<pre>//adding an individual brick object
	private GRect brick;

	//drawing all the bricks necessary for the game
	private void drawBricks(double cx, double cy) {				

		/*need to have several columns in each row
		 * so there need to be two for loops, 
		 * one for loop for the rows and one for loop for the columns.
		 */ 

		for( int row = 0; row < NBRICK_ROWS; row++ ) {

			for (int column = 0; column < NBRICKS_PER_ROW; column++) {

				/* To get the x coordinate for the starting width:
				 * 	start at the center width, 
				 * 	subtract half of the bricks (width) in the row,  
				 * 	subtract half of the separations (width) between the bricks in the row,
				 * now you're at where the first brick should be, 
				 * so for the starting point of the next bricks in the column, you need to: 
				 * 	add a brick width 
				 * 	add a separation width
				 */

				double	x = cx - (NBRICKS_PER_ROW*BRICK_WIDTH)/2 - ((NBRICKS_PER_ROW-1)*BRICK_SEP)/2 + column*BRICK_WIDTH + column*BRICK_SEP;

				/* To get the y coordinate of the starting height:
				 * 	start at the given length from the top for the first row,
				 * 	then add a brick height and a brick separation for each of the following rows
				 */

				double	y = cy + row*BRICK_HEIGHT + row*BRICK_SEP;

				brick = new GRect( x , y , BRICK_WIDTH , BRICK_HEIGHT );
				add (brick);
				brick.setFilled(true);

				//Setting colors depending on which row the bricks are in

				if (row < 2) {
					brick.setColor(Color.RED);
				}
				if (row == 2 || row == 3) {
					brick.setColor(Color.ORANGE);
				}
				if (row == 4 || row == 5) {
					brick.setColor(Color.YELLOW);
				}
				if (row == 6 || row == 7) {
					brick.setColor(Color.GREEN);
				}
				if (row == 8 || row == 9) {
					brick.setColor(Color.CYAN);
				}
			}
		}</pre>

Enjoy the article? Join over 17,500+ Swift developers and enthusiasts who get my weekly updates.

  • From what i’m reading in this code, and pretty much like i saw in every people trying to do this part of assignment no one takes in mind if there is a different number of rows. Wich limit the chance to do different levels fast. I came up with a solution for that wich use’s the %… The exercice that i’v done is from 2012 wich has 4 colors, RED, YELLOW, GREEN, CYAN.

    Wich means RED appears in row 1,2,9,10. repits cycle each 8 rows:
    1%8=1
    2%=2
    9%8=1
    10%8=2
    So using switch condition u can say that all i%8 = 1 or 2 u get red.
    By doing the same to others color for YELLOW 3,4 GREEN 5,6 and CYAN 7,default
    You always get the sequence right no matter if u’v 1 or 9999 rows with 1 or 9999 bricks per row.

    GCanvas gc = new GCanvas();
    gc.setSize(WIDTH, HEIGHT);
    for(int i=1;i<=NBRICK_ROWS;i++){
    for(int j=1;j<=NBRICKS_PER_ROW;j++){
    GRect brick=new GRect(BRICK_WIDTH,BRICK_HEIGHT);
    brick.setFilled(true);
    switch(i%8){
    case 1:
    case 2: brick.setColor(Color.RED);break;
    case 3:
    case 4: brick.setColor(Color.YELLOW);break;
    case 5:
    case 6: brick.setColor(Color.GREEN);break;
    case 7:
    default: brick.setColor(Color.CYAN);break;
    }
    add(brick,(getWidth()/2)-(NBRICKS_PER_ROW*BRICK_WIDTH/2)-((NBRICKS_PER_ROW+3)*BRICK_SEP/2)+(j-1)*(BRICK_WIDTH+BRICK_SEP),BRICK_Y_OFFSET+(i-1)*BRICK_HEIGHT);
    }
    }

    By adding more cases and changing the 8 to NumberofColor*2 you can actually do this for infinity number of Colors. And with pretty much low changing u can do 3 in 3 rows 4 in 4 rows color change. Anyway the most important part is that u can do different levels just by changing the number of rows and number of bricks per row, while keeping the color change every 2 rows.

    • erik

      Hi I am a complete noob to to Java and am having trouble figuring out what cx and cy mean and why people use them as variables. In your code, it doesn’t seem like cx and cy are ever given any values, so how can cx be used to find the x-coordinate of the first column of bricks? I understand the logic of how to find the x-coordinate, but have trouble implementing it in my code. I would think you would use the getWidth method, but for some reason getWidth keeps creating errors when I run it in eclpse.

  • Pingback: CS106A Assignment 3 - Breakout, Part 1: Setting up the Bricks | PROGRAMMING ZERO TO HERO()

  • I just had an idea for this solution:

    	private void buildBricks(){
    		// initial brick creation
    		int initial_x = (getWidth()/BRICK_WIDTH)/BRICK_SEP;
    		int y = BRICK_Y_OFFSET;
    		int x = initial_x;
    		
    		for (int j = 0; j&lt;NBRICK_ROWS; j++){
    			for (int i = 0; i&lt;NBRICKS_PER_ROW;i++){
    				GRect brick = new GRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);
    				
    				// this loop verifies what color corresponds to each row
    				if (j == 0 || j == 1){
    					brick.setFillColor(Color.red);
    				} if (j == 2 || j == 3) {
    					brick.setFillColor(Color.orange);
    				} if (j == 4 || j == 5){
    					brick.setFillColor(Color.yellow);
    				} if (j == 6 || j == 7){
    					brick.setFillColor(Color.green);
    				} if (j == 8 || j == 9){
    					brick.setFillColor(Color.cyan);
    				}
    				
    				brick.setFilled(true);
    				add(brick);	
    				x = x + BRICK_SEP + BRICK_WIDTH;
    				if (i==NBRICKS_PER_ROW-1){
    					x = initial_x;
    					y+=BRICK_HEIGHT + BRICK_SEP; 
    				}
    			}
    		}
    	}
    
  • Nathan

    Yay I got this one done and conquered a big problem I’d been having with my graphics coordinates. Apparently, APPLICATION_HEIGHT includes the file menu (25px high). I ended up having to increase 600 to 625, and editing the {WIDTH/HEIGHT} variables to no longer point to APPLICATION{HEIGHT/WIDTH}. I also added nifty borders which also decreased my game size and forced me to make some mods to my BRICK_WIDTH to make everything fit. After that it was relatively straightforward.

    import acm.graphics.*;
    import acm.program.*;
    import acm.util.*;

    import java.applet.*;
    import java.awt.*;
    import java.awt.event.*;

    public class Breakout extends GraphicsProgram {

    /** Width and height of application window in pixels */
    public static final int APPLICATION_WIDTH = 400;
    public static final int APPLICATION_HEIGHT = 625;

    /** Dimensions of game board (usually the same) */
    private final static int WIDTH = (APPLICATION_WIDTH);
    private final static int HEIGHT = (APPLICATION_HEIGHT-25);

    /** Dimensions of the paddle */
    private static final int PADDLE_WIDTH = 60;
    private static final int PADDLE_HEIGHT = 10;

    /** Offset of the paddle up from the bottom */
    private static final int PADDLE_Y_OFFSET = 30;

    /** Number of bricks per row */
    private static final int NBRICKS_PER_ROW =10;

    /** Number of rows of bricks */
    private static final int NBRICK_ROWS = 10;

    /** Separation between bricks */
    private static final int BRICK_SEP = 4;

    /** Width of a brick */
    private static final int BRICK_WIDTH =
    (WIDTH-30 - (NBRICKS_PER_ROW - 1) * BRICK_SEP) / NBRICKS_PER_ROW;

    /** Height of a brick */
    private static final int BRICK_HEIGHT = 8;

    /** Radius of the ball in pixels */
    private static final int BALL_RADIUS = 10;

    /** Offset of the top brick row from the top */
    private static final int BRICK_Y_OFFSET = 70;

    /** Number of turns */
    private static final int NTURNS = 3;

    /* Method: run() */
    /** Runs the Breakout program. */
    public void run() {
    /* You fill this in, along with any subsidiary methods */
    init();
    }

    public void init(){
    setupBorder();
    setupBricks();

    }

    public void setupBorder(){
    Color brown = new Color(139,69,19);

    rBorder(0,0,WIDTH,HEIGHT,3,Color.BLACK);
    rBorder(6,6,WIDTH,HEIGHT,3,brown);
    rBorder(9,9,WIDTH,HEIGHT,3,Color.BLACK);
    }

    public void setupBricks(){
    Color b = new Color(0,0,0);
    int j=0;
    for(int i=0; i<NBRICK_ROWS; i++){

    if(i%2==0 || i==0){
    j++;
    b=changeColor(j);
    }
    layRow(13+BRICK_SEP,BRICK_Y_OFFSET+i*(BRICK_SEP+BRICK_HEIGHT), b);
    }

    }
    private void layRow(int x, int y, Color b){

    for(int i=0; i<NBRICKS_PER_ROW; i++)
    {
    layBrick((x+i*(BRICK_WIDTH+BRICK_SEP)),y, b);

    }

    }

    public void layBrick(int x, int y, Color argC){
    GRect brick = new GRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);
    fillObj(brick, argC);
    add(brick);
    }

    public Color changeColor(int a){
    switch(a){
    case 1: return Color.RED;
    case 2: return Color.ORANGE;
    case 3: return Color.YELLOW;
    case 4: return Color.GREEN;
    case 5: return Color.CYAN;

    }
    return Color.black;
    }
    public void fillObj(GFillable a, Color argC)
    {
    a.setFillColor(argC);
    a.setFilled(true);
    }

    //** Paints a Rectangle with a Colored Border
    public void rBorder(int x, int y, int boxX, int boxY, int thick, Color argC){
    GRect b = new GRect(x, y, boxX-x*2, boxY-y*2);
    fillObj(b, argC);
    add(b);
    b = new GRect(x+thick, y+thick, boxX-((x+thick)*2), boxY-(y+thick)*2);
    fillObj(b, Color.white);
    add(b);
    }

    }

    • Nathan

      Wierd looks like my code somehow got messed up. let me try again.
      public void setupBorder(){
      Color brown = new Color(139,69,19);

      rBorder(0,0,WIDTH,HEIGHT,3,Color.BLACK);
      rBorder(6,6,WIDTH,HEIGHT,3,brown);
      rBorder(9,9,WIDTH,HEIGHT,3,Color.BLACK);
      }

      public void setupBricks(){
      Color b = new Color(0,0,0);
      int j=0;
      for(int i=0; i<NBRICK_ROWS; i++){
      if(i%2==0 || i==0){
      j++;
      b=changeColor(j);
      }
      layRow(13+BRICK_SEP,BRICK_Y_OFFSET+i*(BRICK_SEP+BRICK_HEIGHT), b);
      }

      }
      private void layRow(int x, int y, Color b){

      for(int i=0; i<NBRICKS_PER_ROW; i++)
      {
      layBrick((x+i*(BRICK_WIDTH+BRICK_SEP)),y, b);

      }

      }

      public void layBrick(int x, int y, Color argC){
      GRect brick = new GRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);
      fillObj(brick, argC);
      add(brick);
      }

      public Color changeColor(int a){
      switch(a){
      case 1: return Color.RED;
      case 2: return Color.ORANGE;
      case 3: return Color.YELLOW;
      case 4: return Color.GREEN;
      case 5: return Color.CYAN;

      }
      return Color.black;
      }
      public void fillObj(GFillable a, Color argC)
      {
      a.setFillColor(argC);
      a.setFilled(true);
      }

      //** Paints a Rectangle with a Colored Border
      public void rBorder(int x, int y, int boxX, int boxY, int thick, Color argC){
      GRect b = new GRect(x, y, boxX-x*2, boxY-y*2);
      fillObj(b, argC);
      add(b);
      b = new GRect(x+thick, y+thick, boxX-((x+thick)*2), boxY-(y+thick)*2);
      fillObj(b, Color.white);
      add(b);
      }

      }