Hi folks, This is more of a general C++ question than a specific RL one. I, like most, intend to have a large number of different terrain tiles. Each terrain currently has the following attributes;
gfxId (ascii char shown) name color totalhitpoints currenthitpoints (terrain is desctructable)
Tile's are like this;
class Tile{ //objects Terrain terrain;
};
At the moment to create my hardcoded map I simply parse the map text file, and depending on the char it creates a tile and populates it's Terrain object. What I'd rather do though is pre create Terrain objects for each Terrain type then when parsing the map file, pass a copy of the correct Terrain to the Tile.
What I'm asking is how to store the definitions for the Terrains and how to load them in with a nice loop. This is where my knowledge of C+ + is lacking. How to do all the nice fluffy macro style stuff that automates things like this. I presume I need my terrain data in a define.h file of a sort. Is there a way to have structs or something defined for this purpose?
On 6 marras, 13:49, skreeg <skr...@gmail.com> wrote:
> What I'm asking is how to store the definitions for the Terrains and > how to load them in with a nice loop.
There is no single proper way to do that, but one thing that you could do is remove Terrain object as Tile's data and use Terrain objects as static data. For example there is no need to copy the tile's name in each Tile class instance unless each tile name can be changed. You can get the name from separate data class/array that holds the static data. I think you should always try to keep dynamic (changing) and static data in different places, so it reduces the copying of data.
The way I do it is I have a text file that defines each object's data. This data is loaded into a base-object-holder before the game begins. The base-object-holder holds only the data that defines the differences between the objects (it would hold the color and the name, but not the current hitpoints). I store all the base-object-holders in a map (or vector) and then when I want to load a grass tile (which would be tile # 4 for example) my createTile function access the data from base-tile-holder[4] (or whatever you decide to call it).
That method doesn't worry about the amount of duplicated information that I copy to all the different tiles. To be more efficient, you can have permanent values (like the name & tile if those never change) and instead of storing them in each tile, just read those from the base- tile-holder and only hold the changing values in the tile (like current hitpoints)
hmm, I think I was making it into a bigger problem than it is. I fairly certain I'm only going to have 20 odd tiles at most so I've "upgraded" my terrain code to just hardcode the details into the Terrain class constructors with a big switch statement parsing an enum terrainType. It'll do just now and I'm not keen on having terrain data outside in an easily editable text file.
> Hi folks, > This is more of a general C++ question than a specific RL one. I, like > most, intend to have a large number of different terrain tiles. Each > terrain currently has the following attributes;
> gfxId (ascii char shown) > name > color > totalhitpoints > currenthitpoints (terrain is desctructable)
> Tile's are like this;
> class Tile{ > //objects > Terrain terrain; > };
> At the moment to create my hardcoded map I simply parse the map text > file, and depending on the char it creates a tile and populates it's > Terrain object. What I'd rather do though is pre create Terrain > objects for each Terrain type then when parsing the map file, pass a > copy of the correct Terrain to the Tile.
> What I'm asking is how to store the definitions for the Terrains and > how to load them in with a nice loop. This is where my knowledge of C+ > + is lacking. How to do all the nice fluffy macro style stuff that > automates things like this. I presume I need my terrain data in a > define.h file of a sort. Is there a way to have structs or something > defined for this purpose?
The way you do it seems reasonable, but what you want to do is easy enough too.
I would use constructors, for example the following constructor would do what I understand you to be doing now:
Now you read your map as normal for the level, but when you read 'g' from the map file, you check to see if there is any 'g' in keys, and if there is you copy the corresponding terrain value for data into map[x] [y], instead of using the default constructor. So you will have a level with grass that is tougher than normal, whereas other terrains will have their default value.
That's more or less what I've done. A simple enum first
enum terrainType{ GRASS, STONEWALL, RUBBLE
};
Then a constructor;
Terrain::Terrain(terrainType_t terrain) { switch (terrain) case GRASS; gfxid='.'; name="Grass"; etc..
}
In GameWorld.generateMap() I create a Terrain object for each terrainType. Read in the mapfile and copy the terrain object into the Tile at map[x][y]. Seems to work well. Damage messages now go directly to &world instead of the dodgy pointer nonsense I had before in Tile objects and I now have destructable terrain. Only thing now is to concentrate on getting my AI working for a release instead of being tempting into coding grenades. :)
I believe this is a good point to let your compiler do some of the work for you. Write a program to take a nice, succinct, version of your data and output C structs with the data. Then you get the best of both worlds.
This is my approach in my 7DRLs and POWDER where enummaker.exe will create the glbdef.cpp and glbdef.h from my source.txt