Showing posts with label Breakout. Show all posts
Showing posts with label Breakout. Show all posts

Wednesday, 9 March 2011

_13_Object

//Objects
//
//So far we have been using simple variables of
//either type 'int' or type 'boolean'.  These are
//called primative types because they are just raw
//data and can only store one value -- they don't
//have any other properties apart from the value
//you set them to.  Most of the time it is more useful
//to use more complex data types which have more than
//one value in them.
//
//For example, if you need to store today's date in your
//programme, you would probably make some int variables
//like this:
//
//  int day = 9;
//  int month = 3;
//  int year = 2011;
//
//This is fine if you are just handling one date but it
//gets really awkward if you need to store lots of dates,
//say for a calender programme.  Another problem is that
//the seperate variables aren't connected in any way even
//though they all belong to the same date.  A better way
//to store the numbers is to wrap them up into a new data
//type by writing a 'class':
//
//  class Date {
//    int day;
//    int month;
//    int year;
//  }
//
//When these three variable declarations are wrapped into
//a class they become a new 'complex' type.  Now we can
//make a variable which has 'Date' as its type:
//
//  Date myBirthday = new Date();
//
//The variable 'myBirthday' has three integers inside it
//with the names we gave them in the Date class.
//You can get at the individual variables like this:
//
//  myBirthday.day = 13;
//
//You write the name of the Date variable followed by a dot
//followed by the name of integer you want to access.
//Using classes is a lot neater than having lots of integer
//variables in your code.
//
//A class can have any kind of variable inside it that you
//want.

//Integer variables
int SCORE = 0;

//Constants
final int blockPoints = 10;

final int screenWidth = 480;
final int screenHeight = 800;

final int blocksPerRow = 10;
final int numRows = 4;
final int blockWidth = screenWidth / blocksPerRow;
final int blockHeight = 20;
final int firstRowYPos = 50;

//Boolean 'flags'
boolean gamePlaying = true;
boolean winner = false;


int [ ] [ ] theBlocks = new int[ numRows ] [ blocksPerRow ];


class Ball {
  final int Size = 10;
 
  int X = 240;
  int Y = 400;

  int Xspeed = 5;
  int Yspeed = -5;
}


class Bat {
  final int Size = 50;
  final int Height = 25;

  int X = 240;
  int Y = 700;
}


Ball ball = new Ball();
Bat bat = new Bat();

//===================================
void setup() {
  size( screenWidth, screenHeight );
  background( 0 );
  noCursor();
 
  setupBlockRows();
}

//
//The draw function is nice and simple
//====================================
void draw() {
  background( 0 );
 
  if( gamePlaying && !winner ) {
    drawScore();
    drawBlocks();
    moveTheBat();
    moveTheBall();
    winner = checkBlocksGone();
  }
  if( !gamePlaying ) {
    gameOver();
  }
  if( winner ) {
    gameWon();
  }
}

//This time the setupBlockRows() function
//uses 'nested' loops to count through each
//row, and then every column in that row.
//Traditionally, loop counters are often called
//'i', 'j' or 'k' especially when you have
//nested loops.
//==================================//
void setupBlockRows() {
//    |   ONE   |     TWO    | THREE |
  for( int i = 0; i < numRows;  i++  ) { 
                                              
    for( int j = 0; j < blocksPerRow; j++ ) { 
      theBlocks[ i ][ j ] = 1;                
    }                                         
  } 
}

//==================================//
void drawBlocks() {
  int rowPosition = firstRowYPos;
 
  fill( 200 );
 
  for( int i = 0; i < numRows; i++ ) {
    drawOneRow( rowPosition, theBlocks[ i ] ); // <- send just one row of the array
    rowPosition = rowPosition + blockHeight;
  }
}

//void drawOneRow( int, int[] )
//
//===================================//
void drawOneRow( int rowLevel, int[] someRow ) {
  int counter;
 
  for( counter = 0; counter < someRow.length; counter++ ) {
    if( someRow[counter] == 1 ) {
      rect( blockWidth * counter + 1, rowLevel + 1, blockWidth - 2, blockHeight - 2 );
    }
  }
}


//====================================
void moveTheBat() {
  fill( 255 );
 
  bat.X = mouseX;
 
  //if the bat 'hits' the left edge move it back
  if( bat.X < bat.Size ) {
    bat.X = bat.Size;
  }
 
  //if the bat 'hits' the right edge move it
  if( bat.X > screenWidth - bat.Size ) {
    bat.X = screenWidth - bat.Size;
  }
 
  rect( bat.X - bat.Size, bat.Y, bat.Size * 2, bat.Height );
}


//=======================================
void moveTheBall() {
  ball.X = ball.X + ball.Xspeed;
  ball.Y = ball.Y + ball.Yspeed;
 
  if( ball.X < ball.Size ) {
    ball.X = ball.Size;
    ball.Xspeed = ball.Xspeed * -1;
  }
 
  if( ball.X > screenWidth - ball.Size ) {
    ball.X = screenWidth - ball.Size;
    ball.Xspeed = ball.Xspeed * -1;
  }
 
  if( ball.Y < ball.Size ) {
    ball.Y = ball.Size;
    ball.Yspeed = ball.Yspeed * -1;
  }
 
  if( ballHitBat() ) {
    ball.Yspeed = ball.Yspeed * -1;
  }
 
  if( ball.Y > screenHeight ) {
    gamePlaying = false;
  }
 
  for( int i = 0; i < numRows; i++ ) {
    checkBallHitRow( theBlocks[ i ], i );
  }
 
  rect( ball.X - ball.Size, ball.Y - ball.Size, ball.Size * 2, ball.Size * 2 );
}



//=================================//
boolean checkBallHitRow( int[] someRow, int rownumber ) {
  int blockLeft;
  int blockRight;
  int blockTop;
  int blockBottom;
  boolean hit = false;
 
  for( int whichblock = 0; whichblock < 10; whichblock++ ) {
    blockLeft   =          0 + blockWidth * whichblock;
    blockRight  = blockWidth + blockWidth * whichblock;
   
    blockTop    =  firstRowYPos                + blockHeight * rownumber;
    blockBottom = (firstRowYPos + blockHeight) + blockHeight * rownumber;
   
    if( ball.X > blockLeft && ball.X < blockRight ) {
      if( ball.Y > blockTop && ball.Y < blockBottom ) {
        if( someRow[whichblock] == 1 ) {
          someRow[whichblock] = 0;
          SCORE += blockPoints;
          hit = true;
        }
      }
    }
  }
 
  return hit;
}
//=======================================//
boolean checkBlocksGone() {
  int totalblocks = 0;
 
  for( int i = 0; i < numRows; i++ ) {
    for( int j = 0; j < blocksPerRow; j++ ) {
      totalblocks += theBlocks[ i ][ j ];
    }
  }
 
  return (totalblocks == 0);
}

//=====================================//
void drawScore() {
  fill( 255 );
  text( "Score: " + SCORE, 10, 10 );
}

//======================================//
void gameOver() {
  fill( 255 );
  text("Game Over", 200, 400);
}

//======================================//
void gameWon() {
  fill( 255 );
  text("WINNER!", 200, 400);
}
 
//======================================//
boolean ballHitBat() {
  if( ball.Y + ball.Size >= bat.Y ) {
    if( ball.Y + ball.Size <= bat.Y + ball.Size * 2 ) {
      if( ball.X > bat.X - bat.Size ) {
        if( ball.X < bat.X + bat.Size ) {
          //the ball has hit the bat so return the answer is 'true'
          return true;
        }
      }
    }
  }
  //if we get this far then the ball hasn't hit, return the answer 'false'
  return false;
}

//mousePressed()
//
//This is another one of Processing's built in functions
//When the mouse button is pressed, Processing automatically
//calls this function so your program can react.
void mousePressed() {
  if( !gamePlaying || winner ) {
    SCORE = 0;
    gamePlaying = true;
    winner = false;
    setupBlockRows();
   
    ball.X = 240;
    ball.Y = 400;
  }
}


Sunday, 6 March 2011

_12_MoreArraysAndLoops

//Integer variables
int batX = 240;
int batY = 700;

int ballX = 240;
int ballY = 400;

int ballXspeed = 5;
int ballYspeed = -5;

int SCORE = 0;

//Constants
final int blockPoints = 10;

final int ballSize = 10;
final int screenWidth = 480;
final int screenHeight = 800;

final int batSize = 50;
final int batHeight = 25;

final int blocksPerRow = 10;
final int numRows = 4;
final int blockWidth = screenWidth / blocksPerRow;
final int blockHeight = 20;
final int firstRowYPos = 50;

//Boolean 'flags'
boolean gamePlaying = true;
boolean winner = false;

//More Arrays:

//Arrays don't have to be 'one dimensional'.  You can set them
//up to use two or more index numbers to access the values they
//contain.  For example if you want a grid of numbers 3 columns
//wide and 4 rows deep, you can set that up like this:
//
//  int [ ] [ ] theGrid = new int[ 3 ][ 4 ];
//
//The variable 'theGrid' acts a bit like a spreadsheet or a table
//in a word processor: you can access each row with the first index,
//and each number in that row with the second index.  So the bottom,
//right hand corner of the grid would be:
//
//  int bR = theGrid[ 2 ][ 3 ];
//
//( Remember array indexes start counting from zero ).  An array
//organized into 'columns' and 'rows' has two indexes and is called
//a 'two dimensional' array.
//
//To work through every value in a two dimensional array, you need to
//write _two_ loops, one *inside* the other.  When loops are put inside
//other loops, they are called 'nested' loops
int [ ] [ ] theBlocks = new int[ numRows ] [ blocksPerRow ];
//   ^   ^
//   |   |
//   R   B
//   o   l
//   w   o
//       c
//   N   k
//   u  
//   m   N
//   b   u
//   e   m
//   r   b
//       e
//       r


//===================================
void setup() {
  size( screenWidth, screenHeight );
  background( 0 );
  noCursor();
 
  setupBlockRows();
}

//
//The draw function is nice and simple
//====================================
void draw() {
  background( 0 );
 
  if( gamePlaying && !winner ) {
    drawScore();
    drawBlocks();
    moveTheBat();
    moveTheBall();
    winner = checkBlocksGone();
  }
  if( !gamePlaying ) {
    gameOver();
  }
  if( winner ) {
    gameWon();
  }
}

//This time the setupBlockRows() function
//uses 'nested' loops to count through each
//row, and then every column in that row.
//Traditionally, loop counters are often called
//'i', 'j' or 'k' especially when you have
//nested loops.
//==================================//
void setupBlockRows() {
//    |   ONE   |     TWO    | THREE |
  for( int i = 0; i < numRows;  i++  ) {  // <-------- N
                                               //      e
    for( int j = 0; j < blocksPerRow; j++ ) {  //      s
      theBlocks[ i ][ j ] = 1;                 //      t
    }                                          //      e
  }  // <--------------------------------------------- d
}

//This function has been changed to use
//the two dimensional arrays to to draw the blocks.
//
//One very important thing to notice: the drawOneRow()
//function hasn't changed; it still expects one int and
//one int array as its inputs.  Even though we are using
//a two dimensional array with rows and columns, we can
//still send it just one row of the array by only putting
//one index after the variable name.
//==================================//
void drawBlocks() {
  int rowPosition = firstRowYPos;
 
  fill( 200 );
 
  for( int i = 0; i < numRows; i++ ) {
    drawOneRow( rowPosition, theBlocks[ i ] ); // <- send just one row of the array
    rowPosition = rowPosition + blockHeight;
  }
}

//void drawOneRow( int, int[] )
//
//===================================//
void drawOneRow( int rowLevel, int[] someRow ) {
  int counter;
 
  for( counter = 0; counter < someRow.length; counter++ ) {
    if( someRow[counter] == 1 ) {
      rect( blockWidth * counter + 1, rowLevel + 1, blockWidth - 2, blockHeight - 2 );
    }
  }
}


//====================================
void moveTheBat() {
  fill( 255 );
 
  batX = mouseX;
 
  //if the bat 'hits' the left edge move it back
  if( batX < batSize ) {
    batX = batSize;
  }
 
  //if the bat 'hits' the right edge move it
  if( batX > screenWidth - batSize ) {
    batX = screenWidth - batSize;
  }
 
  rect( batX - batSize, batY, batSize * 2, batHeight );
}


//=======================================
void moveTheBall() {
  ballX = ballX + ballXspeed;
  ballY = ballY + ballYspeed;
 
  if( ballX < ballSize ) {
    ballX = ballSize;
    ballXspeed = ballXspeed * -1;
  }
 
  if( ballX > screenWidth - ballSize ) {
    ballX = screenWidth - ballSize;
    ballXspeed = ballXspeed * -1;
  }
 
  if( ballY < ballSize ) {
    ballY = ballSize;
    ballYspeed = ballYspeed * -1;
  }
 
  if( ballHitBat() ) {
    ballYspeed = ballYspeed * -1;
  }
 
  if( ballY > screenHeight ) {
    gamePlaying = false;
  }
 
  for( int i = 0; i < numRows; i++ ) {
    checkBallHitRow( theBlocks[ i ], i );
  }
 
  rect( ballX - ballSize, ballY - ballSize, ballSize * 2, ballSize * 2 );
}

//boolean checkBallHitRow(int[], int)
//
//This function works out the position of each block in
//a row, then works out if the ball is inside the block.
//If it is, the function sets the value for the block to zero in
//the array for that row.  Later on when the rows are
//drawn, the blocks which have value zero in the array
//don't get drawn so it looks like the ball has destroyed
//them.
//
//NEW: the if tests in this function check TWO things
//at once.  The first 'if' looks like this:
//
//  if( ballX > blockLeft && ballX < blockRight )
//
//In plain English it says:
//"If the value of'ballX' is greater than 'blockLeft',
//AND the value of 'ballX' is less than blockRight, then
//run the next bit of code"
//
//The two tests are being combined into one more complex
//test by the '&&' symbol.  && stands for AND.  The combined
//test is only true if BOTH the first and second test are
//true.  There are other ways of combining tests:
//
//  ||    Means OR, it is true if the first OR second test is true
//  !     (Exclamation point) means NOT - it reverses the meaning
//        of a test 'true' becomes 'false' and 'false' becomes 'true'
//
//Tests can be grouped together by putting them between parenthesis ()
//
//=================================//
boolean checkBallHitRow( int[] someRow, int rownumber ) {
  int blockLeft;
  int blockRight;
  int blockTop;
  int blockBottom;
  boolean hit = false;
 
  for( int whichblock = 0; whichblock < 10; whichblock++ ) {
    blockLeft   =          0 + blockWidth * whichblock;
    blockRight  = blockWidth + blockWidth * whichblock;
   
    blockTop    =  firstRowYPos                + blockHeight * rownumber;
    blockBottom = (firstRowYPos + blockHeight) + blockHeight * rownumber;
   
    if( ballX > blockLeft && ballX < blockRight ) {
      if( ballY > blockTop && ballY < blockBottom ) {
        if( someRow[whichblock] == 1 ) {
          someRow[whichblock] = 0;
          SCORE += blockPoints;
          hit = true;
        }
      }
    }
  }
 
  return hit;
}
//=======================================//
boolean checkBlocksGone() {
  int totalblocks = 0;
 
  for( int i = 0; i < numRows; i++ ) {
    for( int j = 0; j < blocksPerRow; j++ ) {
      totalblocks += theBlocks[ i ][ j ];
    }
  }
 
  return (totalblocks == 0);
}

//=====================================//
void drawScore() {
  fill( 255 );
  text( "Score: " + SCORE, 10, 10 );
}

//======================================//
void gameOver() {
  fill( 255 );
  text("Game Over", 200, 400);
}

//======================================//
void gameWon() {
  fill( 255 );
  text("WINNER!", 200, 400);
}
 
//======================================//
boolean ballHitBat() {
  if( ballY + ballSize >= batY ) {
    if( ballY + ballSize <= batY + ballSize * 2 ) {
      if( ballX > batX - batSize ) {
        if( ballX < batX + batSize ) {
          //the ball has hit the bat so return the answer is 'true'
          return true;
        }
      }
    }
  }
  //if we get this far then the ball hasn't hit, return the answer 'false'
  return false;
}

//mousePressed()
//
//This is another one of Processing's built in functions
//When the mouse button is pressed, Processing automatically
//calls this function so your program can react.
void mousePressed() {
  if( !gamePlaying || winner ) {
    SCORE = 0;
    gamePlaying = true;
    winner = false;
    setupBlockRows();
   
    ballX = 240;
    ballY = 400;
  }
}

Friday, 4 March 2011

_11_Arrays

int batX = 240;
int batY = 700;

int ballX = 240;
int ballY = 400;

int ballXspeed = 5;
int ballYspeed = -5;

//
final int ballSize = 10;
final int screenWidth = 480;
final int screenHeight = 800;

final int batSize = 50;
final int batHeight = 25;

//
boolean gamePlaying = true;
boolean winner = false;

//
final int blocksPerRow = 10;
final int blockWidth = screenWidth / blocksPerRow;
final int blockHeight = 20;
final int firstRowYPos = 50;

//Arrays:
//An array is like a list of data.  It could
//be a list of numbers, words, images, sounds
//or any other kind of data you can think of.
//
//There are a few important things to know
//about arrays.
//
//First, you define an array variable like an
//ordinary variable except the variable type
//is a bit different (see sketch 04 for more
//on variable types).  The type of an array
//has square brackets [] straight after the
//type of data the array should store.  To
//have a list of words, you need to store text
//data.  The type that represents text is 'String'
//so a list of words can be stored as an array of
//Strings.  To define a variable call 'theWordList'
//as an array of Strings you would write:
//
//  String[] theWordList;
//
//It looks just like a simple String variable but
//it has sqaure brackets added to the data type.
//
//The next thing to learn about arrays is that they
//are a fixed length -- once you set the size of the
//array, you can't add extra items to the list.  You
//can set the size of the array at the same time that
//you define its name like this:
//
//  String[] theWordList = new String[10];
//
//the command 'new' tells Processing to 'allocate' (which
//just means reserve) some memory to store the array.
//Next the type of data is repeated and followed by the
//length of the array in brackets.  So this line of code
//'declares' an array of Strings called 'theWordList' which
//has 10 items in it.  At the moment their aren't any
//Strings in the array -- it just has 10 empty slots where
//we can put text data.  Using an array is much easier than
//creating 10 String variables with different names.
//
//The most important thing to remember about arrays is how
//you get and set the values in it.  Once you have made a
//new array, you can get to each of the slots in it by putting
//the slot number in the brackets after the name.  So to set
//slot 3 in the array to the word "ninja" you would write:
//
//  theWordList[3] = "ninja";
//
//To print out the value in slot 6 with the println() function
//you could write:
//
//  String theValue = theWordList[6];
//  println( theValue );
//
//The one unexpected thing about slot numbers is that they
//start at ZERO.  So the _first_ slot in the array is:
//
//  theWordList[0]
//
//and, counting ten slots starting with ZERO makes the _last_ slot:
//
//  theWordList[9]
//
//There are still 10 slots its just the numbering which is
//a bit confusing.  If you try to get or set a slot which is
//outside the length of the array, you will get an error called
//an 'ArrayIndexOutOfBoundsException' and the program will stop
//so this line would crash the program:
//
//  theWordList[16] = "crash";  // <- no slot 16!
//
//You can always find out the size of an array by getting its
//'length' property:
//
//  int myArraySize = theWordList.length;
//  println("There are " + myArraySize + " slots in the array");
//
int[] rowA = new int[10];
int[] rowB = new int[10];
int[] rowC = new int[10];
int[] rowD = new int[10];

//===================================
void setup() {
  size( screenWidth, screenHeight );
  background( 0 );
  noCursor();
 
  setupBlockRows();
}

//
//The draw function is nice and simple
//====================================
void draw() {
  background( 0 );
 
  if( gamePlaying && !winner ) {
    drawBlocks();
    moveTheBat();
    moveTheBall();
  }
  if( !gamePlaying ) {
    gameOver();
  }
  if( winner ) {
    gameWon();
  }
}

//This function sets up the arrays of ints which
//represent the rows of blocks.  It is just a loop
//which sets each slot in each array to the the
//number one.
//
//There are a couple of new ideas in this loop.
//First, the counter variable for the loop is
//called 'i'.  Also we can define the variable
//in part ONE of the for statement (see example
//_10_Loops).  In part THREE there is the expression:
//
//  i++
//
//which is a short hand way of writing:
//
//  i = i + 1
//
//==================================//
void setupBlockRows() {
//    |   ONE   |  TWO  | THREE |
  for( int i = 0; i < 10;  i++  ) {
    rowA[i] = 1;
    rowB[i] = 1;
    rowC[i] = 1;
    rowD[i] = 1;
  }
}

//This function has been changed to use
//the int arrays to to draw the blocks.
//==================================//
void drawBlocks() {
  int rowPosition = firstRowYPos;
 
  fill( 200 );
 
  drawOneRow( rowPosition, rowA );
  rowPosition = rowPosition + blockHeight;
 
  drawOneRow( rowPosition, rowB );
  rowPosition = rowPosition + blockHeight;
 
  drawOneRow( rowPosition, rowC );
  rowPosition = rowPosition + blockHeight;
 
  drawOneRow( rowPosition, rowD );
  rowPosition = rowPosition + blockHeight;
}

//void drawOneRow( int, int[] )
//
//Now this function takes two inputs, the
//position of the row in pixels, like before,
//(int rowLevel) and the int array representing
//the blocks.  This time, the loop counts upto
//the number of slots in each array.  Then it
//checks if the value in the slot equals the
//number one.  IMPORTANT: look at the 'if'
//statement.  It gets the value of a slot in
//the array with this code:
//
//  someRow[counter]
//
//as the loop repeats, counter goes up by one
//each time (see the function setupBlockRows() for
//more), then it tests if the value it got out
//of the array equals 1 like this:
//
//  slotRow[counter] == 1
//
//notice that there are TWO equals characters
//back to back here.  This is a special symbol
//which *compairs* two numbers.  One equals
//character on its own would *set* the value
//of the slot in the array to the number one
//NOT compair it to one.
//===================================//
void drawOneRow( int rowLevel, int[] someRow ) {
  int counter;
 
  for( counter = 0; counter < someRow.length; counter++ ) {
    if( someRow[counter] == 1 ) {
      rect( blockWidth * counter + 1, rowLevel + 1, blockWidth - 2, blockHeight - 2 );
    }
  }
}


//====================================
void moveTheBat() {
  fill( 255 );
 
  batX = mouseX;
 
  //if the bat 'hits' the left edge move it back
  if( batX < batSize ) {
    batX = batSize;
  }
 
  //if the bat 'hits' the right edge move it
  if( batX > screenWidth - batSize ) {
    batX = screenWidth - batSize;
  }
 
  rect( batX - batSize, batY, batSize * 2, batHeight );
}


//=======================================
void moveTheBall() {
  ballX = ballX + ballXspeed;
  ballY = ballY + ballYspeed;
 
  if( ballX < ballSize ) {
    ballX = ballSize;
    ballXspeed = ballXspeed * -1;
  }
 
  if( ballX > screenWidth - ballSize ) {
    ballX = screenWidth - ballSize;
    ballXspeed = ballXspeed * -1;
  }
 
  if( ballY < ballSize ) {
    ballY = ballSize;
    ballYspeed = ballYspeed * -1;
  }
 
  if( ballHitBat() ) {
    ballYspeed = ballYspeed * -1;
  }
 
  if( ballY > screenHeight ) {
    gamePlaying = false;
  }
 
  checkBallHitRow( rowA, 0 );
  checkBallHitRow( rowB, 1 );
  checkBallHitRow( rowC, 2 );
  checkBallHitRow( rowD, 3 );
 
  winner = checkBlocksGone();
 
  rect( ballX - ballSize, ballY - ballSize, ballSize * 2, ballSize * 2 );
}

//boolean checkBallHitRow(int[], int)
//
//This function works out the position of each block in
//a row, then works out if the ball is inside the block.
//If it is, the function sets the value for the block to zero in
//the array for that row.  Later on when the rows are
//drawn, the blocks which have value zero in the array
//don't get drawn so it looks like the ball has destroyed
//them.
//
//NEW: the if tests in this function check TWO things
//at once.  The first 'if' looks like this:
//
//  if( ballX > blockLeft && ballX < blockRight )
//
//In plain English it says:
//"If the value of'ballX' is greater than 'blockLeft',
//AND the value of 'ballX' is less than blockRight, then
//run the next bit of code"
//
//The two tests are being combined into one more complex
//test by the '&&' symbol.  && stands for AND.  The combined
//test is only true if BOTH the first and second test are
//true.  There are other ways of combining tests:
//
//  ||    Means OR, it is true if the first OR second test is true
//  !     (Exclamation point) means NOT - it reverses the meaning
//        of a test 'true' becomes 'false' and 'false' becomes 'true'
//
//Tests can be grouped together by putting them between parenthesis ()
//
//=================================//
boolean checkBallHitRow( int[] someRow, int rownumber ) {
  int blockLeft;
  int blockRight;
  int blockTop;
  int blockBottom;
  boolean hit = false;
 
  for( int whichblock = 0; whichblock < 10; whichblock++ ) {
    blockLeft   =          0 + blockWidth * whichblock;
    blockRight  = blockWidth + blockWidth * whichblock;
   
    blockTop    =  firstRowYPos                + blockHeight * rownumber;
    blockBottom = (firstRowYPos + blockHeight) + blockHeight * rownumber;
   
    if( ballX > blockLeft && ballX < blockRight ) {
      if( ballY > blockTop && ballY < blockBottom ) {
        someRow[whichblock] = 0;
        hit = true;
      }
    }
  }
 
  return hit;
}
//=======================================//
boolean checkBlocksGone() {
  int totalblocks = 0;
 
  for( int i = 0; i<rowA.length; i++ ) {
    totalblocks += (rowA[i] + rowB[i] + rowC[i] + rowD[i]);
  }
 
  return (totalblocks == 0);
}

//======================================//
void gameOver() {
  fill( 255 );
  text("Game Over", 200, 400);
}

//======================================//
void gameWon() {
  fill( 255 );
  text("WINNER!", 200, 400);
}
 
//======================================//
boolean ballHitBat() {
  if( ballY + ballSize >= batY ) {
    if( ballY + ballSize <= batY + ballSize * 2 ) {
      if( ballX > batX - batSize ) {
        if( ballX < batX + batSize ) {
          //the ball has hit the bat so return the answer is 'true'
          return true;
        }
      }
    }
  }
  //if we get this far then the ball hasn't hit, return the answer 'false'
  return false;
}

_10_Loops

int batX = 240;
int batY = 700;

int ballX = 240;
int ballY = 400;

int ballXspeed = 5;
int ballYspeed = -5;

//
final int ballSize = 10;
final int screenWidth = 480;
final int screenHeight = 800;

final int batSize = 50;
final int batHeight = 25;

//
boolean gamePlaying = true;

//
final int blocksPerRow = 10;
final int blockWidth = screenWidth / blocksPerRow;
final int blockHeight = 20;

//===================================
void setup() {
  size( screenWidth, screenHeight );
  background( 0 );
  noCursor();
}

//
//The draw() function is nice and simple
//====================================
void draw() {
  background( 0 );
 
  if( gamePlaying ) {
    drawBlocks();
    moveTheBat();
    moveTheBall();
  } else {
    gameOver();
  }
}

//void drawBlocks()
//
//This function introduces a few new programming
//ideas.  The first one is quite simple.  You can
//have variables _inside_ a function; called 'local'
//variables, these values are 'trapped' inside the
//function and can't be used anywhere outside it, so
//the names 'counter' and 'rowPosition' only exist
//in the drawBlocks() function.  You can store any
//number you like in them but when the function ends,
//they are forgotten.
//
//The second idea is the 'for' loop.  In programming,
//you almost always have to do something over and over
//again.  They way you can repeat a piece of code is to
//put it inside a loop.
//
//A loop is just a block of code plus a counter variable.
//The block of code runs over and over until the counter
//reaches a certain value.
//
//The 'for' loop has four separate parts:
//
//  for( ONE; TWO; THREE ) {
//    FOUR;
//  }
//
//ONE: this is the bit that sets the _starting_ value for
//the counter.
//TWO: this is the bit that checks if the counter has reached
//the final value (it is a lot like the code in an 'if' test
//THREE: this bit makes the counter count up (or down).
//FOUR: this is the block of code which gets repeated however
//many times the loop goes round.
//==================================//
void drawBlocks() {
  int counter;
  int rowPosition = 50;
 
  fill( 200 );
 
  // The parts of a for loop:
  //   |   ONE    |     TWO    |       THREE          |  //
  for( counter = 0; counter < 4; counter = counter + 1 ) {
    // FOUR
    drawOneRow( rowPosition );
    rowPosition = rowPosition + blockHeight;
  }
}

//===================================//
void drawOneRow( int rowLevel ) {
  int counter;
 
  for( counter = 0; counter < blocksPerRow; counter = counter + 1 ) {
    rect( blockWidth * counter + 1, rowLevel + 1, blockWidth - 2, blockHeight - 2 );
  }
}


//====================================
void moveTheBat() {
  fill( 255 );
 
  batX = mouseX;
 
  //if the bat 'hits' the left edge move it back
  if( batX < batSize ) {
    batX = batSize;
  }
 
  //if the bat 'hits' the right edge move it
  if( batX > screenWidth - batSize ) {
    batX = screenWidth - batSize;
  }
 
  rect( batX - batSize, batY, batSize * 2, batHeight );
}


//=======================================
void moveTheBall() {
  ballX = ballX + ballXspeed;
  ballY = ballY + ballYspeed;
 
  if( ballX < ballSize ) {
    ballX = ballSize;
    ballXspeed = ballXspeed * -1;
  }
 
  if( ballX > screenWidth - ballSize ) {
    ballX = screenWidth - ballSize;
    ballXspeed = ballXspeed * -1;
  }
 
  if( ballY < ballSize ) {
    ballY = ballSize;
    ballYspeed = ballYspeed * -1;
  }
 
  if( ballHitBat() ) {
    ballYspeed = ballYspeed * -1;
  }
 
  if( ballY > screenHeight ) {
    gamePlaying = false;
  }
 
  rect( ballX - ballSize, ballY - ballSize, ballSize * 2, ballSize * 2 );
}

//======================================
void gameOver() {
  fill( 255 );
  text("Game Over", 200, 400);
}

//======================================
boolean ballHitBat() {
  if( ballY + ballSize >= batY ) {
    if( ballY + ballSize <= batY + ballSize * 2 ) {
      if( ballX > batX - batSize ) {
        if( ballX < batX + batSize ) {
          //the ball has hit the bat so return the answer is 'true'
          return true;
        }
      }
    }
  }
  //if we get this far then the ball hasn't hit, return the answer 'false'
  return false;
}

_09_BetterGamePlay

int batX = 240;
int batY = 700;

int ballX = 240;
int ballY = 400;

int ballXspeed = 5;
int ballYspeed = -5;

//So far we have put all the sizes of
//the bat and the ball straight into the code
//where they are being used.  There are at least
//two problems with this.  First it means that
//we have to enter the same number in lots of
//places in the code so it gets really annoying to
//change the size of the bat and the ball.  Secondly
//having meaningless numbers all over the code makes
//it hard to read because there is no clue about what
//the number represents.
//
//In this version of the code, we are going
//to replace the 'hard coded' numbers with 'constants'
//which are values a bit like variable except that they
//never change during the program.  You can make a value
//constant by putting the word 'final' in front of its
//definition.  Now we can replace all the numbers in
//the code with the constant name which solves both
//problems: the code is much easier to read because
//it has meaningful words instead of raw numbers in it,
//and now there is only one place we have to change a
//value to make changes to the size of the bat, ball or
//screen.  Look through the code to find all the places
//where each constant is used, then try changing the
//values to see how easy it is to make things different
//sizes.
final int ballSize = 10;
final int screenWidth = 480;
final int screenHeight = 800;

final int batSize = 50;
final int batHeight = 25;

//boolean gamePlaying
//
//This is a new variable.  Its 'type' is boolean
//which means it can have the value 'true' or the
//value 'false'.  It is used in the draw() function
//to decide when to show the game over screen.
//A variable which can switch from true to false
//is often called a 'flag' in programming speak.
boolean gamePlaying = true;

//===================================
void setup() {
  size( screenWidth, screenHeight );
  background( 0 );
  noCursor();
}

//
//The draw() function is nice and simple
//====================================
void draw() {
  background( 0 );
 
  if( gamePlaying ) {
    moveTheBat();
    moveTheBall();
  } else {
    gameOver();
  }
}



//====================================
void moveTheBat() {
  fill( 255 );
 
  batX = mouseX;
 
  //if the bat 'hits' the left edge move it back
  if( batX < batSize ) {
    batX = batSize;
  }
 
  //if the bat 'hits' the right edge move it
  if( batX > screenWidth - batSize ) {
    batX = screenWidth - batSize;
  }
 
  rect( batX - batSize, batY, batSize * 2, batHeight );
}


//=======================================
void moveTheBall() {
  ballX = ballX + ballXspeed;
  ballY = ballY + ballYspeed;
 
  if( ballX < ballSize ) {
    ballX = ballSize;
    ballXspeed = ballXspeed * -1;
  }
 
  if( ballX > screenWidth - ballSize ) {
    ballX = screenWidth - ballSize;
    ballXspeed = ballXspeed * -1;
  }
 
  if( ballY < ballSize ) {
    ballY = ballSize;
    ballYspeed = ballYspeed * -1;
  }
 
  if( ballHitBat() ) {
    ballYspeed = ballYspeed * -1;
  }
 
  if( ballY > screenHeight ) {
    gamePlaying = false;
  }
 
  rect( ballX - ballSize, ballY - ballSize, ballSize * 2, ballSize * 2 );
}

//======================================
void gameOver() {
  fill( 255 );
  text("Game Over", 200, 400);
}

//======================================
boolean ballHitBat() {
  if( ballY + ballSize >= batY ) {
    if( ballY + ballSize <= batY + ballSize * 2 ) {
      if( ballX > batX - batSize ) {
        if( ballX < batX + batSize ) {
          //the ball has hit the bat so return the answer is 'true'
          return true;
        }
      }
    }
  }
  //if we get this far then the ball hasn't hit, return the answer 'false'
  return false;
}

_08_SimpleGamePlay

int batX = 240;
int batY = 700;

int ballX = 240;
int ballY = 400;

int ballXspeed = 10;
int ballYspeed = 10;

//===================================
void setup() {
  size( 480, 800 );
  background( 0 );
}

//
//
//====================================
void draw() {
  background( 0 );
 
  moveTheBat();
  moveTheBall();
}


//
//This is just the same as in example 06
//====================================
void moveTheBat() {
  fill( 255 );
 
  batX = mouseX;
 
  //if the bat 'hits' the left edge move it back
  if( batX < 50 ) {
    batX = 50;
  }
 
  //if the bat 'hits' the right edge move it
  if( batX > 430 ) {
    batX = 430;
  }
 
  rect( batX - 50, batY, 100, 25 );
}

//
//This is basically the same as before except
//that this time, the ball doesn't bounce off
//the bottom of the screen.  Instead we use a
//function (not a built in one, we write it
//ourselves) to check if the ball hits the
//bat.
//=======================================
void moveTheBall() {
  ballX = ballX + ballXspeed;
  ballY = ballY + ballYspeed;
 
  if( ballX < 5 ) {
    ballX = 5;
    ballXspeed = ballXspeed * -1;
  }
 
  if( ballX > 475 ) {
    ballX = 475;
    ballXspeed = ballXspeed * -1;
  }
 
  if( ballY < 5 ) {
    ballY = 5;
    ballYspeed = ballYspeed * -1;
  }
 
  if( ballHitBat() ) {
    ballYspeed = ballYspeed * -1;
  }
 
  rect( ballX - 5, ballY - 5, 10, 10 );
}

//
//This function does the work of checking
//if the ball hits the bat.  There is a lot
//of new ideas in this small function.  First
//thing to notice is that the 'return type' of
//the function is 'boolean' instead of void.
//A boolean is a type of variable which can have
//the value 'true' or 'false'.  When the function
//detects that the ball and bat collide, it 'returns'
//the value 'true' as the answer.  We can use that
//answer somewhere else in the code to do something.
//If there hasn't been a collision then the function
//returns 'false'.  When a function 'returns' an answer
//it stops there and the program goes back to where ever
//it left off (which will be where ever the function
//was 'called').
//
//Another new idea introduced here is 'nested' if
//statements.  You can put an if test _inside_ another
//if test.  That way you can test for more complex
//situations.  _if_ the first test is true, then it
//checks the next test.  _if_ that's true then it
//checks the next one and so on.
//======================================
boolean ballHitBat() {
  if( ballY >= batY ) {
    if( ballX > batX - 50 ) {
      if( ballX < batX +50 ) {
        //the ball has hit the bat so return the answer is 'true'
        return true;
      }
    }
  }
  //if we get this far then the ball hasn't hit, return the answer 'false'
  return false;
}

_07_SimpleAnimation

int ballX = 240;
int ballY = 400;

int ballXspeed = 10;
int ballYspeed = 10;

void setup() {
  size( 480, 800 );
  background( 0 );
}

void draw() {
  background( 0 );
 
  moveTheBall();
}

//
void moveTheBall() {
  ballX = ballX + ballXspeed;
  ballY = ballY + ballYspeed;
 
  if( ballX < 5 ) {
    ballX = 5;
    ballXspeed = ballXspeed * -1;
  }
 
  if( ballX > 475 ) {
    ballX = 475;
    ballXspeed = ballXspeed * -1;
  }
 
  if( ballY < 5 ) {
    ballY = 5;
    ballYspeed = ballYspeed * -1;
  }
 
  if( ballY > 795 ) {
    ballY = 795;
    ballYspeed = ballYspeed * -1;
  }
 
  rect( ballX - 5, ballY - 5, 10, 10 );
}

_06_Functions

int batX = 240;
int batY = 700;


//Here we go again
void setup() {
  size( 480, 800 );
  background( 0 );
}

//Here the code to control and draw the bat has been moved out of the 'draw' function
//which is now a lot simpler.  The program does exactly the same thing as before,
//the code has just been reorganized a bit.  This makes the 'draw' function much easier
//read.
void draw() {
  background( 0 );

  moveTheBat();
}

//This is not a built in function.  We can define as many of our own functions
//as we need and use them from (almost) anywhere we want.
void moveTheBat() {
  fill( 255 );
 
  batX = mouseX;
 
  //if the bat 'hits' the left edge move it back
  if( batX < 50 ) {
    batX = 50;
  }
 
  //if the bat 'hits' the right edge move it
  if( batX > 430 ) {
    batX = 430;
  }
 
  rect( batX - 50, batY, 100, 25 );
}

_05_If_Statements

int batX = 240;
int batY = 700;


//Here we go again
void setup() {
  size( 480, 800 );
  background( 0 );
}

//This time the white rectangle is going to follow the mouse
//but only side-to-side so the code sets the value of 'batX' to
//equal the built in variable 'mouseX'.  Also, each time Processing draws a
//frame we check the current value of 'batX'.  If the bat is going over
//the side of the window, we can just change the value of 'batX' to
//put it back on the screen before we actually draw it.  This way it looks
//as if the bat is bumping up against the edge of the window.
void draw() {
  background( 0 );
  fill( 255 );
 
  batX = mouseX;
 
  //if the bat 'hits' the left edge move it back
  if( batX < 50 ) {
    batX = 50;
  }
 
  //if the bat 'hits' the right edge move it
  if( batX > 430 ) {
    batX = 430;
  }
 
  rect( batX - 50, batY, 100, 25 );
}

_04_MoreVariables

//This time we are going to define some variables of
//our own to store some information.  Like a function
//name, a variable definition has three parts.
//First is the variable "type".  This tells Processing
//what kind of information the variable contains.  In
//this example it is:
//
//  int
//
//'int' is short for Integer which just means a whole number
//like 3 , 17 or 19234
//
//An int _can't_ store a fraction.
//
//The next part is a label which is the name of the variable
//You can pick just about any namne for your variable so long as
//A) it starts with a letter
//B) it is a single word with no spaces
//C) it isn't the same as any built in name or label
//
//Finally there is an optional start value for the variable
//The start value is set only once, after that we can change
//the variable inside one of the functions and the variable
//will remember the new value.
//
//There are lots of other variable types that Processing understands
//some of the most commonly used ones are:
//
//  float   |  a 'float' stores fractions like 3.14 or 2.737
//  boolean |  this type can only have the value 'true' or 'false'
//  String  |  a sequence of letters and numbers stored as text
//
int batX = 240;
int batY = 700;


//Here we go again
void setup() {
  size( 480, 800 );
  background( 0 );
}

//Draw a white rectangle in the middle bottom of the screen.
//This time we are using the value of a variable to set the
//position of the rectangle.  Also, you can use some maths to
//work out the final position.
void draw() {
  fill( 255 );
  rect( batX - 50, batY, 100, 25 );
}

_03_Variables

//Same as before...
void setup() {
  size( 480, 800 );
  background( 0 );
}

//This time the draw function is a little different.
//The position of the rectangle isn't a fixed number.
//Instead the built in values 'mouseX' and 'mouseY'
//are used.  These two values store the left-to-right
//position of the mouse cursor (mouseX) and the top-to-bottom
//position of the mouse (mouseY).  The values of 'mouseX' and
//'mouseY' change as the mouse moves about so they are called
//"variables".  You can create your own variables to store
//any information your program needs.
void draw() {
  fill( 255 );
  rect( mouseX, mouseY, 80, 80 );
}

_02_SimpleDrawing

//This sketch starts the same as the one before
//I've written a function called 'setup' which
//sets the size of the window.
//Then I've added a new command which sets the
//background colour of the window.  The parameter
//sets the background colour to a shade of grey:
//0 means black and 255 means white.
void setup() {
  size(480, 800);
  background(0);
}

//void draw()
//
//'draw' is another one of the built in functions
//that Processing knows about.  It doesn't give back
//an answer and it doesn't let you send it any information
//as parameters.  Processing 'calls' the draw function 60 times
//a second so if you draw something different each time you can
//make an animation.  For now it just sets the drawing colour
//with the 'fill' command which works the same as the 'background'
//command (guess what colour it will draw).  Then it draws a
//rectangle with the 'rect' command.  The numbers between the
//braces are the position of the top left corner of the rectangle
//and the width and height, all in pixels.
//Try changing the code to draw two rectangles on the screen.
void draw() {
  fill(255);
  rect( 200, 360, 80, 80 );
}

_01_Basics

//void setup()
//
//This is a function called 'setup'
//A function is like a question or command
//you can ask Processing
//Every function name has three parts,

//First is the "return type" which is:
//
//  void
//
// 'void' means that this fuction doesn't
//actually give back an answer, it just silently
//does some work.
//The next part of the function name is picked by you
//It can be almost anything and should describe what the
//function does.  In this example the name is
//
//   setup
//
//This function is built into Processing.  It runs once
//at the begining of your program and is the best place to
//get everything ready before the animation starts.
//
//Finally there is a list of 'parameters'.  Parameters are
//just places for you to send information into the function
//so you can get it to do different things each time you
//call it.
//
//'Calling' a function is the same as 'Asking' a question
//
//For the 'setup' function there aren't any parameters -- it
//just does one thing in the same way every time and you can't
//send it any information so the parameter list is just written
//as a pair of braces with nothing between them like this:
//
//  ()
//
//After the function is the function 'body'.  This is a list of
//other commands that do the actual work of the function.  The
//body is put inside a pair of curly braces {  body  }
//
//The body of setup only has one command in it:
//
//  size(480, 800);
//
//'size' is another built in Processing command.  It sets the
//size of the window for the application (480 pixels by 800 pixels).
//The numbers in between the braces are the 'parameters'.
//Try changing them to make windows of different sizes.
void setup() {
  size(480, 800);
}