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;
}

No comments:

Post a Comment

Note: only a member of this blog may post a comment.