Home This Article Is Taken From The Game Programming MegaSite, A Definitive Resource For Game Developers!

Further Into Tile Techniques
By: JiiQ

Introduction

This is something I threw together after reading all of the other very excellent tile algorthims found on GPMega. In this tutorial, I'll show you how to do most of what was said in those, with some of my own twists and improvements.

Maps are HUGE

This has to be the most important aspect of tile based game programming. The size of your map array determines how much memory is needed to play the game, and even how big the file size of your exe/dat/map files are. Let's start from the beginning.

Most tile based games define a tile structure that holds info on each tile of the map, and so the members in those structures need to be as few and as small as possible. You say you want to include things like frame-delay times, a bitmap index for each frame, movability, and even more in your tiles? Trying to save an array of structures with alot of big members into a map file (or in any other format) will really hog disk space (and take forever to download). One solution to this is RLE compression, where instead of writing each tile at a time into the file, you write an extra number for each tile. The extra being the number of tiles ahead of that one that are exactly the same. Therefore skipping the need to write any continous identicles into the map file. But being a structure array, and having to check, compare, and save each member at a time, this tends to be more trouble than it's worth. The other big issue is the memory your map will be hogging. It's just not necessary.

Creating Tile Properties Seperate

First, create a 'tile_properties' structure. In this structure, include all of the static properties that are used in your map. For an example, say you have a grass tile that is movable, and sways the grass back and forth as if the wind is blowing. All of these properties are static, meaning they will never change. If, however, you're creating a top-down perspective, and have something like say a tree placed on only certain grass tiles, that would not be a static property. Because not every grass tile will have a tree. You could easily create two static 'tile_properties' members though. One for grass, and one for grass with a tree. This is actually not a big deal.

Anyway, back to the tile_properties array. This array will only be as big as the number of different tiles you will have in your game (or the current level, ect), and will look like this:



	struct tile_properties {

		int bitmap1, bitmap2, ect..		// For each frame if animated
		int delay_1, delay_2, ect..		// Also for each frame if animated
		int movable;				// If it can be walked on
		ect..					// Any number of other properties

	} tile_info[256];

You don't have to declare the tile_info array gobal as it seems I did above, but it may be necessary. Also the number (256) would be the actual ammount of different types of tiles you want to have. As you can see, I declared everything as int's, and not unsigned char's. The reason being that integers are faster to work with, and after reading on, you'll find that size isn't as big an issue in this array.

Creating the Actual Map Array

Before creating your map array, you need to decide how static your tiles are. If you keep characters and/or items stored in your tiles, you will need to create a new structure for your map to include those certain non-static properties into the members of your array. But first let me show you how to create a completely static set of tiles:



	unsigned char map[MAP_X_MAX][MAP_Y_MAX];

	// or if you use pointers:

	unsigned char *map;

Yep, that's it. Your map array only holds one value, ranging from 0-255, for each property index. If you need more property types, you can declare your map as integers (this also might actually make it faster to work with). To assign a tile in your map to contain the certain unique properties of say tile_properties[3], simply do the following:



	// For arrays:

	map[x][y] = 3;

	// For pointers:

	*(map+x+(y*width)) = 3;

And for accessing the properties of a map tile, lets just pretend we're in the middle of a move-guy function, and we need to check a certain tile to see if it's movable. Also pretend this function recieves the x and y values of the tile to check, to keep it simple:



	int check_movable(int x, int y) {

		return tile_properties[map[x][y]].movable;

		// or tile_properties[*(map+x+(y*width))].movable for pointers

	}

When updating regular tile routines, like changing frames, you now only need to update the tile_properties array, and not even touch the map array. As you can see, we're not losing any functionality, and at the same time making our map array faster to work with and reducing the size of it tremendously. As said above, this method is for static-tiles only. Meaning other tiles of the same type don't contain any different information. But if you want, say a grass tile, to sometimes be non-movable, you would need to create two grass-type tile_property entries. One for movable, and one for not. This is actually not a big deal if you ask me, but there may be unique cases where it is. So below is the solution:



	struct map_tiles {

		unsigned char p;
		int movable;

	} map[MAP_X_MAX][MAP_Y_MAX];

You can also declare any additional members you need for other non-static properties. The 'p' member is actually the same as all of the examples above, where map[x][y].p would replace the plain map[x][y]. For example:



	int check_movable(int x, int y) {

		return tile_properties[map[x][y].p].movable;

		// or tile_properties[(map+x+(y*width))->p].movable for pointers

	}

Accessing the non-static properties would be doing so without the use of tile_properties:



	int check_for_guy(int x, int y) {

		return map[x][y].is_guy_here;

		// or *(map+x+(y*width))->is_guy_here for pointers

	}

This tactic doesn't limit you in any way. And just as a note, I've never needed non-static tiles, and never had the need to create a structure for the map array. You can do just about everything without it, so it makes it that much better. If you have any ideas that add to mine, or surpass mine, I would love to hear about them. Please send me an email.



The Game Programming MegaSite - ⌐1996- Matt Reiferson.