Sign in to follow this  
Mekuri

What is the optimal way to store a tile based world in an array?

Recommended Posts

Mekuri    301
Hey there.
For a while I've been working on a 2d tile based side scroller (Think Terraria).

I've spend a little week now reading up on game design in general, which ended up with me questioning my current methods.
Currently my world is an array of a class I call "Tile". Tile contains a lot of information, like type, collision information, and information about whether gravity affect it, and so on. My concern is, that I am wasting a lot of memory this way?
Now I have a few solutions in mind, but I can't decide which one would be the best, or if I even need to change anything at all.
The first one would be to simply have an array of integers where each number represents a certain tile type. My concern with this method is that for every cycle I will spend a lot of cpu power instead, since I will need to do hundreds of switch cases every cycle, to determine the behavior, and what to draw everytime a number is encountered in the array.
My second solution would be a more object oriented approach, by creating a base class for the tiles, and each tile type then inherrits from that class. This way only the tiles that require special variables and methods, will get those, wile the more simple tiles will require much less memory.
If the second solution is the better one, is it then viable to check for the tile type simply by using the is statement.
An example:
[CODE]
if(world[x,y] is DirtTile)
{
//Draw DirtTile (or whatever :) )
}
[/CODE]

Is that a wrong way of doing it? Or should I keep some kind of identifier in the class? - Currently I have an enumerator that holds the tile type.

Thank you for reading, and I look forward to any input [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

Share this post


Link to post
Share on other sites
laztrezort    1058
What I have done in the past, is store an identifier in each cell, which can be used to lookup data about that terrain type from a database of terrain types. Then use the terrain data to draw, check movement, or whatever else.

Something like this (pseudocode):

[code]
class Tile
{
int TerrainIndex;
...
}
...
class TerrainType
{
Image image;
bool IsWalkable;
...
}
...
List<TerrainType> TerrainTypes...
...
DrawTile(Cell cell)
{
Image img = TerrainTypes[cell.TerrainIndex];
Renderer.DrawImage(img);
}
[/code]

Thinking of cells as "just data" in this way should eliminate the need for switch cases or messy inheritance. This also allows you to keep the terrain data separate from implentation, say in a text file, that can be tweaked outside of diving through layers of code.

Differentiate between "static" and "dynamic" data. Static data can go in the database, it will not change on a per-cell basis. Dynamic data (state) can change from cell to cell, thus needs to be stored for each cell. Example of possible static data: movement blocking, sprite image, flags such as causes_damage or is_transparent, etc. Examples of possible dynamic data: per cell light level, damage level, etc. There is no hard rule for which belongs where - it depends on the gameplay, how the rendering is set up, etc.

Share this post


Link to post
Share on other sites
Mekuri    301
[quote name='laztrezort' timestamp='1347653444' post='4980161']
What I have done in the past, is store an identifier in each cell, which can be used to lookup data about that terrain type from a database of terrain types. Then use the terrain data to draw, check movement, or whatever else.

Something like this (pseudocode):

[code]
class Tile
{
int TerrainIndex;
...
}
...
class TerrainType
{
Image image;
bool IsWalkable;
...
}
...
List<TerrainType> TerrainTypes...
...
DrawTile(Cell cell)
{
Image img = TerrainTypes[cell.TerrainIndex];
Renderer.DrawImage(img);
}
[/code]

Thinking of cells as "just data" in this way should eliminate the need for switch cases or messy inheritance. This also allows you to keep the terrain data separate from implentation, say in a text file, that can be tweaked outside of diving through layers of code.

Differentiate between "static" and "dynamic" data. Static data can go in the database, it will not change on a per-cell basis. Dynamic data (state) can change from cell to cell, thus needs to be stored for each cell. Example of possible static data: movement blocking, sprite image, flags such as causes_damage or is_transparent, etc. Examples of possible dynamic data: per cell light level, damage level, etc. There is no hard rule for which belongs where - it depends on the gameplay, how the rendering is set up, etc.
[/quote]

This is an awesome Idea. I Really like it. I really look forward to cleaning up my code, and this will help me immensely.

Thank you very much for a quick and well explained answer :)

Share this post


Link to post
Share on other sites
laztrezort    1058
[quote name='Mekuri' timestamp='1347660978' post='4980206']
Thank you very much for a quick and well explained answer [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]
[/quote]

Sure, athough reading back through it I hope it made sense - I was in a hurry when I typed that out [img]http://public.gamedev.net//public/style_emoticons/default/rolleyes.gif[/img]

One thing I want to clarify:

[quote]
Dynamic data (state) can change from cell to cell, thus needs to be stored for each cell.
[/quote]

I should have said dynamic data (state) can change each [i]frame[/i], and needs to be [i]associated[/i] with the cells in some way - the simplest way being to store the state directly in the Cell objects.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this