Tile Maps (Static)
This is part 1 of a series of articles about programming techniques for Tile Map engines, commonly used in 2D video games.
Complex maps have multiple layers, scrolling, animations, isometric views, etc. Before we get to the advanced maps, we need to begin with the simplest map possible.
In this lesson we'll render a Chess board. Here's how we want the final view to appear:

We have several data elements that go into this scene:
- The blank chessboard background image ("Background")
- The images for individual chess pieces ("Tile Set")
- A 2D array holding the current chess piece positions ("Tile Map")
The Background

Here's our blank chess board. We could render it from dark/light tiles, but for this lesson we'll use a whole image. Our chess board in this example is 256x256 pixels, with each tile being 16x16.
Image board = new Image("chessboard.png");
The Tile Set

Here I'm using a .gif with a transparent background. Each piece fits comfortably into a 16x16 tile.
To build the Tile Set, we first we enumerate what can exist in any one space on a chess board:
enum Piece {
empty_space,
white_pawn,
white_rook,
white_knight,
white_bishop,
white_queen,
white_king,
black_pawn,
black_rook,
black_knight,
black_bishop,
black_queen,
black_king
};
Next, we load our tile set into an image array:
Image[] tile_set = new Image[13];
// Copy/Load the white pawn image into tile_set[Piece.white_pawn]
// etc.
The Tile Map
We'll store the current state of the game board in a 2D array.
Piece[][] tile_map = new Piece[8][8];
We'll use this array as tile_map[column][row], with the top-left corner being [0][0]. We can assign the starting board positions:
// setup the game board
tile_map[0][0] = Piece.white_rook;
tile_map[1][0] = Piece.white_knight;
tile_map[2][0] = Piece.white_bishop;
...
tile_map[0][2] = Piece.empty_space;
...
// etc
The Render
To redraw the current scene, we take the following steps:
- Draw the blank chess board over the previous screen
- Loop through all rows/columns of the chess board
- If this slot isn't empty (no chess piece) ...
- Determine the (x,y) screen location of this chess piece
- Draw the chess piece onto the screen at that location
Here's the code:
void render() {
// screen (x,y) is the pixel position on the screen to draw a game piece
int screen_x;
int screen_y;
// assuming a library function:
// void draw(Image src, Image dest, int dest_x, int dest_y);
// draw the blank chess board
draw(board, screen, 0, 0);
// loop through the chess spaces and draw any pieces
for (int row=0; row<8; row++) {
screen_y = row * 16; // 16 = tile pixel height
for (int column=0; column<8; column++) {
screen_x = column * 16; // 16 = tile pixel width
if (tile_map[column][row] != Piece.empty_space) {
draw(tile_set[tile_map[column][row]], screen, screen_x, screen_y);
}
}
}
} // end render();
This two-dimensional render loop is common to almost all tile map engines, and is fairly easy to understand. In the next article, we'll look at how to scroll the viewscreen around a large game map.
Clint Bellanger is using these articles to help keep his code legible. He is a writer for PFunked.
This article is released under the terms of the Creative Commons Share-Alike License. The source code listed above is released under the terms of the GNU Public License