Saturday, January 7, 2012

KAPOW! Tile Creation Part: Two


Now, we want to actually store the array of data to be used to create the visible tiles.

In our nested for loops we'll be replacing "//code to create tiles" with a block of code that will fill each item in the array with the following information:
The cell's ID
The background Image associated with it
The Row number
The Column number
So let's get started...

    for (y=0;y<tH;y++)
    {
        console.log("Row :" + y);
        for (x=0;x<tW;x++)
        {
            //console.log("Column :" + x);
            if (x > 0 && x < (tW - 1) && y > 0 && y < (tH - 1))
            {
               
                var randomnumber=Math.floor(Math.random()*tR);
                if(randomnumber > 2 )
                {
                    cell[i] = {'id':i , 'bgImage':undefined, 'row':y, 'column':x};
                }
                if(randomnumber == 0)
                {
                    cell[i] = {'id':i , 'bgImage':'orangeTile', 'row':y, 'column':x};
                }
                if(randomnumber == 1)
                {
                    cell[i] = {'id':i , 'bgImage':'blueTile', 'row':y, 'column':x};
                }
                if(randomnumber==2)
                {
                    cell[i] = {'id':i , 'bgImage':'greenTile', 'row':y, 'column':x};
                }               
            }
            else
            {                   
                    cell[i] = {'id':i , 'bgImage': undefined, 'row':y, 'column':x};
            }
            i++;
        }
    }
This is code we'll put in the second for loop.  Let's break this down.
if (x > 0 && x < (tW - 1) && y > 0 && y < (tH - 1)){}
This is our if statement that checks which row and column we're in.  It also makes sure we haven't reached the end of the game screen.  This IF statement will basically create a border of tiles around the "game space"... these cells can be used for UI elements or whatever, but for this example it just creates space between the outer border of the screen and the tiles, but in a way that allows us to change the attributes later.
x>0 && x<(tW -1)
These comparative statements check that X is greater than Zero, &&(and), X is less than the number of tiles accross (minus one).  The reason we use tW - 1 and >0 (instead of greater than equal to ) is because we don't want to add cell data for the outer rows/columns... this will create a border effect.  If we wanted to fill the whole game screen with tiles, we would simply drop the -1 and check if x is greater than equal to zero.
  y > 0 && y < (tH - 1)
This is the exact same thing, except done for the Y axis.  And basically says if you're not at the end of the page (minus the border), keep going... if you've reached the end of the game screen, stop.
&& means AND
then everything between {} is what will be executed if all conditions are true.  If we replaced && with || we would be doing OR...
|| means OR
Which would return true if ANY of the conditions are true... very important later.

the ELSE to this IF catches all the cells on the border.
    for (y=0;y<tH;y++)
    {
        console.log("Row :" + y);
        for (x=0;x<tW;x++)
        {
            //console.log("Column :" + x);
            if (x > 0 && x < (tW - 1) && y > 0 && y < (tH - 1))
            {
                     //animated tile spaces
            }
            else
            {                   
                    //border tile spaces
            }
        }
    }
Now that we're correctly cycling through our cells, we need to add items to our array...  But what is our array?
function createTiles(tW, tH, tR, size) {   
    window.cell = new Array();
...
 The first thing our "createTiles" function needs to do (apparently), is create the array.  Otherwise, where would we store this data we're creating?
window.cell = newArray();
This creates our empty array.

Now that we have our array... we can go back to our IF statement and fill this array with data.
cell[i] = {'id':i , 'bgImage':undefined, 'row':y, 'column':x};
Remember our associative array example?  if not:


Understanding how associative arrays work,  we can see that cell[i] is given the following properties and values:
id = i (our current cell increment)
bgImage = undefined (we don't have an image yet)
row = y (our current row)
column = x (our current column) 
 But if you look closely you'll see there's this variable "i" that isn't defined.

What is I?
"i" is basically a one off variable used to increment something... this could be any name, but is most commonly "i".  If you're looking at someone's code and there's "i" being used, they're most definitely incrementing something somewhere... usually within the function or object and "i" is rarely a global variable... because it's not descriptive at all.

Now, go back to the beginning of your function (just outside of the for loops) and create the variable "i".
var i = 0;
This will set "i" to zero every time the function is called.


Incrementing
incrementing a number is easy.
i++;
What's not so straight forward, is when to increment.

I usually always increment AFTER I've used the number.

So in this case, it makes sense to create the cell with i being 0 and then increment it after the array is populated.

cell[i] = {'id':i , 'bgImage':undefined, 'row':y, 'column':x};
i++;
Now, every time the if statement is true, it will create the cell with the current value of "i", and then increment "i" so long as we are still in the "FOR LOOP".

Now, all of our tiles are being created with the background image 'undefined'.  Let's change that.  Here's the tiles:






Save the images, or create your own, it doesn't matter.
I saved these in my "images" folder of this project.

Let's change "undefined" to "purpleTile";
cell[i] = {'id':i , 'bgImage':'purpleTile', 'row':y, 'column':x};
 Now, every cell is being created with 'purpleTile' set to the bgImage property.

But we have 4 different tiles, how do we randomly place those in the array?



Randomization
Math.random()
This will return a random number that looks like this
 0.9849653994339609
Notice that it's less than 1.  This is because a random number generated with a value greater than one wouldn't be very useful, because you would then have no real control over it.

That's why we do:
Math.random() * range
if range = 10, then the number returned would be something like:
9.849653994339609
This isn't very useful for us either, because of all the decimal points... we don't need all that noise, so we want to drop everything after the decimal by doing this:
Math.floor(Math.random() * range)
This will return 9 if range is 10.
But this is only useful if we assign it to avariable
var randomnumber = Math.floor(Math.random() * range);
Now that we have our random number we can use it to change the properties we put into cell with an IF statement.
if(randomnumber > 2 )
{
     cell[i] = {'id':i , 'bgImage':'purpleTile', 'row':y, 'column':x};
}
This will make every instance where randomnumber is > 2 set to the defined properties.

What if it's not greater than 2?

if(randomnumber > 2 )
{
     cell[i] = {'id':i , 'bgImage':'purpleTile', 'row':y, 'column':x};
}
else
{
     cell[i] = {'id':i , 'bgImage':undefined, 'row':y, 'column':x};
}
So now, if the randomnumber variable is < 2 we'll fill it with a cell who's background image is undefined.

If the random number is equal to a specific value, we can set it to a specific style.  For instance, if randomnumber = 0 and we want all instances of 0 to be the orange tile.
if(randomnumber > 2 )
{
      cell[i] = {'id':i , 'bgImage':'purpleTile', 'row':y, 'column':x};
}
if(randomnumber == 0)
{
     cell[i] = {'id':i , 'bgImage':'orangeTile', 'row':y, 'column':x};
}
else
{
      cell[i] = {'id':i , 'bgImage':undefined, 'row':y, 'column':x};
}
The ELSE case in this example is not going to be used in the final function, as we have a tile for all the cases we will be checking for in the final version, but the example is still valid for understanding how this IF statement works.  If you wanted to keep it in, you could, but it would never be fired in the final example code.

Notice that instead of saying "if(randomnumber = 0)"... where the = is, we instead use ==... this is because == says, "is equal to" and = says, "is" which are two completely different things...

randomnumber = 0 will do two things... First it will set the variable randomnumber to 0, and then will return true.

So, not only are you getting a false positive, but you're resetting "randomnumber" to be 0.


Never forget 
= is
== is equal to
Next, we'll go over how to turn this into actual Div elements in your HTML page.


function createTiles(){}

Here's our function for createTiles()
function createTiles(tW, tH, tR, size) {   
    window.cell = new Array();
    window.visableCells = 0;
       
    var i = 0;

    for (y=0;y<tH;y++)
    {
        console.log("Row :" + y);
        for (x=0;x<tW;x++)
        {
            //console.log("Column :" + x);
            if (x > 0 && x < (tW - 1) && y > 0 && y < (tH - 1))
            {               
                var randomnumber=Math.floor(Math.random()*tR);
                if(randomnumber > 2 )
                {
                    cell[i] = {'id':i , 'bgImage':undefined, 'row':y, 'column':x};
                }
                if(randomnumber == 0)
                {
                    cell[i] = {'id':i , 'bgImage':'orangeTile', 'row':y, 'column':x};
                }
                if(randomnumber == 1)
                {
                    cell[i] = {'id':i , 'bgImage':'blueTile', 'row':y, 'column':x};
                }
                if(randomnumber==2)
                {
                    cell[i] = {'id':i , 'bgImage':'greenTile', 'row':y, 'column':x};
                }               
            }
            else
            {   
                     cell[i] = {'id':i , 'bgImage': undefined, 'row':y, 'column':x};
            }
            i++;
        }
    }
}

Now we can use the array "cell" to create our tiles!  Let's do that in Part Three!
Hope this was helpful!

No comments:

Post a Comment