"Active" Tiles
Firstly, I'm very sorry if this is the wrong place for this question.
I've been working on my 2D tile engine and have run into the problem of having to choose tiles by hand when making my maps. The ones that need to be changed depending on their surrounding tiles, dark and light grass, for instance.
If anyone has used the RPGMaker series (Enterbrain?), they will know what I'm talking about. That program uses blocks of 12 tiles in their resource files and in the map editor, you only see a representation of that tile set and use it to "paint" your scene. The program then chooses the appropriate tile using the surrounding tiles.
I have been looking all around for a simple way of doing this in my own program, I was wondering if anyone knows of a way to do this? Help is greatly appreciated.
What you're thinking about is implementing context sensitivity in your map editor, so that when you paint a tile it is able to use the surrounding tiles to determine it's final representation. This isn't difficult to implement, but it does take some planning if you want to get it right without tediously coding every possible permutation of surrounding tile states.
The first thing you should do is try to categorize your tiles. For instance, if you have 10 tile graphics of dirt that each look different but still look good together, put them into a "dirt0" group. If you have another 10 dirt tiles that look good with each other, but not with the first 10 dirt tiles, create another group and call is "dirt1". Repeat for every category of tile you have. This way you can evaluate tiles based on their group rather than on the actual tile.
You then have to think about transition tiles, ie. those that take you from grass to dirt, sand to water, etc. You can either have dedicated transition tiles that take you from one tile type to another, or you can have special blended tiles that contain two tile types and can be used independently. As an example, let's say you have a field of grass and you want to place a single patch of dirt in the middle. Using dedicated transition tiles, the dirt tile would be 100% dirt and the 8 neighboring tiles would be grass/dirt transition tiles. Using blended tiles, you would place a single tile that had a little tiny bit of dirt in the middle with grass around the edges. This minimizes your dependence on transition tiles, but since the border of the tile is used to transition you only get a little dirt in the middle versus the 100% of the tile that was for dirt in the first case. Or you could just use both.
Finally, the thing about context sensitive tiles is that they depend on the tiles next to them. So when one tile changes, you also have to update the tiles next to it. And if those tiles subsequently change you have to update the tiles next to them, and so on until all the tiles have been updated. In essence you'll be doing a search through all the tiles that need to be updated until they all have been updated. Under certain conditions this could degenerate into an infinite loop if some tiles don't have a steady state (ie. keep changing back and forth every time you go to update them). So be careful designing your context conditions, or have a limit on the number of times a tile can be updated. In the end, it may be more effort to implement a perfectly robust system that works under all conditions than it is to have one that the mapper can enable/disable and then tweak tiles manually.
In terms of implementation, it comes down to each tile type/group implementing its own context logic. You have 8 neighboring tiles, and you have to check to see what they are in order to determine what the current tile should be. It may look something like this:
That's a simple example that doesn't take into account the infinite updating, but it just shows the basic logic flow.
[Edited by - Zipster on January 2, 2006 1:33:28 AM]
The first thing you should do is try to categorize your tiles. For instance, if you have 10 tile graphics of dirt that each look different but still look good together, put them into a "dirt0" group. If you have another 10 dirt tiles that look good with each other, but not with the first 10 dirt tiles, create another group and call is "dirt1". Repeat for every category of tile you have. This way you can evaluate tiles based on their group rather than on the actual tile.
You then have to think about transition tiles, ie. those that take you from grass to dirt, sand to water, etc. You can either have dedicated transition tiles that take you from one tile type to another, or you can have special blended tiles that contain two tile types and can be used independently. As an example, let's say you have a field of grass and you want to place a single patch of dirt in the middle. Using dedicated transition tiles, the dirt tile would be 100% dirt and the 8 neighboring tiles would be grass/dirt transition tiles. Using blended tiles, you would place a single tile that had a little tiny bit of dirt in the middle with grass around the edges. This minimizes your dependence on transition tiles, but since the border of the tile is used to transition you only get a little dirt in the middle versus the 100% of the tile that was for dirt in the first case. Or you could just use both.
Finally, the thing about context sensitive tiles is that they depend on the tiles next to them. So when one tile changes, you also have to update the tiles next to it. And if those tiles subsequently change you have to update the tiles next to them, and so on until all the tiles have been updated. In essence you'll be doing a search through all the tiles that need to be updated until they all have been updated. Under certain conditions this could degenerate into an infinite loop if some tiles don't have a steady state (ie. keep changing back and forth every time you go to update them). So be careful designing your context conditions, or have a limit on the number of times a tile can be updated. In the end, it may be more effort to implement a perfectly robust system that works under all conditions than it is to have one that the mapper can enable/disable and then tweak tiles manually.
In terms of implementation, it comes down to each tile type/group implementing its own context logic. You have 8 neighboring tiles, and you have to check to see what they are in order to determine what the current tile should be. It may look something like this:
class ContextTile{public: ContextTile(int x, int y, int type) x_(x), y_(y), type_(type) {} virtual void DoContext() { // Determine proper type based on neighboring tiles int new_type = DetermineProperType(x, y, type); if(new_type != type) { // Call DoContext on each neighboring tile } }private: int x_, y_; int type_;};void PlaceTile(int x, int y, int type){ ContextTile* tile = new ContextTile(x, y, type); tileList.push_back(tile); tile->DoContext();}
That's a simple example that doesn't take into account the infinite updating, but it just shows the basic logic flow.
[Edited by - Zipster on January 2, 2006 1:33:28 AM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement