Draw A Tile Map
Welcome to the first example in this series of tile based tutorials. This example covers drawing tile images to the screen using a tile map, which is just an array of numbers indicating which tile graphics to draw where. As you can see in the example below, each tile space can be referenced either with a row and column or an index. Each tile space also has a value. The tile value is what's stored in the tile map array. Take a gander:
As you can see, tile maps allow you to make complex scenes from a small set of reusable graphics. Consider the index and the value of each tile space. These two values are directly linked to the one dimensional tile map array. Say I have an array that looks like this:
var array = [ 10, 11, 12, 13 ];
That's a one dimensional array full of values. The value at index 0 is 10, the value at index 1 is 11, and so on. The example above uses the same method for referencing tile values with a much larger array: 256 tile spaces to be exact.
Now if I want to calculate the row and column of a given tile space in the map, I will need some more information about the map. Actually, all that is needed is the number of columns in the map. The example map has 16 columns, but lets take a look at it on a smaller scale. Back to the four valued array we go! Before accessing this array using two dimensions, let's just do a simple reformat to illustrate my point.
// Say this array represents a tile map with two columns and two rows. var array = [ 10, 11, 12, 13 ]; // Here's the same array reformatted to illustrate two columns and two rows. var array = [ 10, 11, 12, 13 ];
As you can see, nothing has actually changed. It's still a one dimensional map. But say I want to get the value at column 0, row 0 in the map. Can you guess which value that is in the reformatted map? If you guessed 10, you were right. But simply reformatting code won't allow you to reference values this way. Like everything else you'll need some code to do the work for you. Here's how to convert a one dimensional index into row and column values:
var column = index % map.columns; var row = Math.floor( index / map.columns );
That's precisely how the example above calculates row and column from index in the output pane. If you plug the values you see in the output into these equations, you'll see that they work quite nicely. Remember that the map above has 16 columns in all.
There's still one more step to drawing graphics to the screen, and that's adjusting the row and column values to fit world space, which is measured in pixels. In the example, each tile is 16x16 pixels. If you want to calculate a tile's position from it's row and column in the map it's as simple as multiplying row and column by the tile's height and width respectively. And that's that.
One other thing you should know is how to convert row and column values back into a single index. This is used to get an object's tile position in the map from its two dimensional coordinates which is pretty important. Say you want to work backwards from an object's physical x, y location in the map; here's how:
var column = Math.floor( object.x / map.columns ); var row = Math.floor( object.y / map.rows ); var index = row * map.columns + column;
As will be the trend throughout these tutorials, if you want a really in depth look at what makes the examples tick, I recommend you take a look at the source code, which is readily available on GitHub or in your browser's developer tools. You can also use the view source feature or I'm sure there are numerous other ways to get a hold of the source files. Such is the nature of JavaScript.
Source Game Loop