My game engine now has scrolling tilemaps in it. I have arbitrarily chosen each tile to be 32×32 pixels, and the maps to contain 256×256 tiles. This gives me a virtual display of 8192×8192 pixels to make tile-based games in. 8192×8192 pixels is a lot… just over 67million pixels. Storing that as a bitmap would require a bit more RAM than my PC has.
This is why tilemaps are good. Big game areas, not much RAM usage.
Drawing them is easy. Draw tiles in a bitmap, then have a 2D array that says where each tile goes. Each tile is numbered, starting at zero. Scrolling is easy too, you just draw a different part of the 2D array on the screen. This makes a slightly jerky scrolling tilemap though since the smallest unit you can scroll is one tile, rather than one pixel. To implement smooth pixel-based tilemap scrolling requires a little bit of thought.
Not much mind.
I did it by having an offscreen buffer that was two tiles larger in both axes than the screen, giving me a 1 tile wide border around the screen. Now, when scrolling, I copy that buffer onto the screen, adding or subtracting an offset to decide which part of the offscreen buffer to use. When the edge of the buffer is hit, I reset the screen back to the centre of the buffer, and redraw it using a different part of the tilemap.
Enough waffle, here’s some code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | void TileMap::DrawMap(BITMAP *bitmap) { masked_blit (buffer, bitmap, scr_xoff, scr_yoff, 0, 0, buffer->w, buffer->h); } void TileMap::RenderMap() { for (int y = map_yoff; y < map_yoff + buf_theight; y++) { for (int x = map_xoff; x w / tile_size)) * tile_size; int yy = (tilemap[x][y] / (int)(tiles->w / tile_size)) * tile_size; blit (tiles, buffer, xx, yy, (x - map_xoff) * tile_size, (y - map_yoff) * tile_size, tile_size, tile_size); } } } void TileMap::ScrollMap(int x, int y) { map_xoff = x / 32; map_yoff = y / 32; scr_xoff = x % 32; scr_yoff = y % 32; RenderMap(); } |
Note that the ScrollMap() function doesn’t test for wandering off the edge of the map, and it dumbly redraws the whole map every time. These are things I will change later.
For a video of it in action, click this link.

