Tileset Problem?

Started by
4 comments, last by GameDev.net 24 years, 4 months ago
I personally use a tile cache system that allows an unlimited number of tilesets, and each tileset can have 65536 tiles. I seperate graphics into different sets - terrain, characters, objects, etc.

To store a tile in the map, you store the pointer to the tileset structure, along with the number of the tile in that set.

As for attributes, just store them in the map structure seperatly from the tiles, that way you can reuse tiles and have different attributes assigned to them.

Something like:

typedef struct {
TILESET *tileset; // tileset pointer
unsigned short tile; // tile number
long attributes; // map attributes
} MAP_SECTION;

MAP_SECTION[MAP_HEIGHT][MAP_WIDTH];


Jim Adams

Advertisement
Is it really the best way, to save a pointer to the used tileset for each map coordinate? In the moment i planned only to save the tileset file names in the header, but your way seems to be also not bad...
One more question, what infos do you save in your tileset structure...
ok thanks for answering...
I hope this might help:

I use 2 caching systems:
1. map section caching
2. tile caching

Lets work with a small example. Say you have a map, 256x256. I divide this into a 4x4 grid of sections. Each map element, is a 32 bit unsigned long. I use half, 16 bits for a tile index into a tile set defined by that section. This allows me to store 65535 tiles per section. The other 16 bits are used for attributes, walkable etc.

Now the rendering engine, asks the map cache manager, where we are on the map. The map manager figures out what map sections need to be drawn. The map manager keeps 4 sections in memory at any time, once we encounter a section that was not loaded from disk previously, the manager evicts one map section and replaces it with the new one. (you can use your own eviction rules, LRU (Least recently used) is a common one.)

This way you can walk through your map, seemlessly, and the map manger handles the loading of sections for you, so your map size is virtually unlimited.
An example layout of map sections would be:

1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16

You see the most sections that are displayable at anyone time is 4, that is if you are in the viewable area of 4 sections.(Hence the 4 cache entries, for performance issues, you might want to increase the cache size) And each section contains 64x64 elements.

So now when the render as for a map element, the map manager handles the loading/caching of its sections and returns a 32 bit value. Half contains a tile index, the other a tile set identifier.

We then pass this info onto the Tile Cache manager, who examines it's cache to see if that tile set is currently loaded. If not it loads it, and returns the tile bitmap to the renderer. It uses the same caching system as the map manager (Base class abstracted), with a larger cache size.

The beauty of this system, is that it's abstracted at a level that makes it easy to use. Given any x,y location, your renderer code might look like this:

.
.
.
while(y{
while(x {
tileinfo = MapManger->GetMapElement(x,y);
surface = TileManager->GetTileBitmap(tileinfo);
Blit surface at appropriate location
}
y++;
}

Obviously this is a small example, I use larger map sections, map size and a slightly more complicated tile/object caching system, but the essential design is the same.

For Jim:
I don't quite understand your pointer to a tileset, and how that works? When you loaded a map from disk, each map element's tileset pointer would be different each time? i.e your tileset gets allocated to a differnt memory location each time your program is run. Also wouldn't you have to populate this element with the tileset pointer each time you loaded a map.

my personal method is to use two classes to manage my tiles. one class manages an individual tile set, and the other manages all of the tilesets you are using.

a tileset object manages the tiles found within a single file (be it a bmp, slp or whatever). a tileset object manages the tileset objects, providing access to the individual tiles usually through some sort of STL vector.

if a given tile's appearance is used only once with a single attribute, then it is best to hold these attributes within the tileset itself. if a given tile's appearance is used in conjunction with more than one attribute, then it might be better to put it into the map information, or to make a terrain lookup table to act as an intermediary.

Get off my lawn!

Hi,
I am programming a isometric engine in the moment. Everything goes fine, and it is also really fast.
Now I started writing a editor for it. Now I am thinking about TILESETS? I am not really sure how i have to use it... do I have to store the image data there + the tile attributes or what ??? And how do I then know which tile is where on the map.. using a TileID may be good, but how do I then determ which tile to blit. ( think i have more then 300 tiles !! ) .. thanks for everyone how can tell me more about tilesets ans how to use then clever..

bye philipp

The pointer is just an internal deal - don't store that in the file. In my current engine, since I only use one tileset per map, you can just store the tile number. That was more of an example above.

Althought, you could rather store an index into a tileset array instead of using a pointer. Also, since I use a tileset for other things, a sprite would need a tileset pointer to refer to, which is set at run-time.

If you were to page maps in, I would use the index method, and just store a list of tilesets to use. When a section of map pages in that uses a tileset, just open it.

I personally don't page maps in, since the maps in my game can be altered, buildings blown up, etc. You'd have to page map sections in and out too much.

I'm about to start looking into paging in maps, but keeping a seperate file of the modified sections of the map to load in as well, but that would take up some good HD space, especially when having multiple save-games.

Jim Adams

This topic is closed to new replies.

Advertisement