Quote:Original post by namingway
I have a field class which is a map, it stores the needed tiles, what would be a good way of creating a tile array? at the moment its Tile _tiles[9];
But obviously then it all maps would have to be that size...
Boost::multi_array.
Quote:Second question here is my current map loading code, what would be a better way of doing it?
Don't write Init() functions. Use constructors.
Also, your loop is wrong: currently you try to set *each* tile to *every* (x, y) location combination, and they all end up in the bottom-right. What you want to do is just have the x and y loops, and increment i in the inner loop.
Try to avoid redundant information, too. Doesn't the image to use depend exactly on the "type" of the tile? So just remember the type inside the Tile, and when it comes time to draw, look up the appropriate SDL_Surface* using that type value. In fact, you don't need to calculate and store the x and y positions of tiles ahead of time; when you're iterating through to draw them, you can recalculate the values. Meanwhile, the Field doesn't need to remember the "maxTiles"; it can calculate that as just height * width. Although, if you use something nice like boost::multi_array, it will remember the dimensions for you, too :)
Quote:And the map drawing code
*** Source Snippet Removed ***
Don't "ask" a class for its data. "Tell" the class to do something, and have it "tell" its data to others, as needed. In general, give tasks to those objects which have the best access to the information required for those tasks.
Putting those hints together, we get something like:
// where '_tiles' is declared as boost::multi_array<Tile, 2>Field::Field(int width, int height): _tiles(boost::extents[width][height]){ for (boost::multi_array<Tile, 2>::iterator it = _tiles.begin(); it != tiles.end(); ++it) { // TODO: get a different "type" for each tile somehow (maybe // read from a file?) // Of course, you could set 0 as the default parameter for the // Tile constructor, too... *it = Tile(0); }}// Notice I add some flexibility here, to draw the field at some given screen// location instead of just the origin. You will probably appreciate this later// ;) Notice how, by not storing the tile locations within the tiles, we can// draw the field anywhere we like without updating any tile contents.void Field::Draw(int xpos, int ypos, SDL_Surface* screen){ int height = _tiles.shape()[0]; int width = _tiles.shape()[1]; for(int y = 0; y < height; y++) { for(int x = 0; x < width; x++) { _tiles[x][y].Draw(x * 32 + xpos, y * 32 + ypos, screen); } }}void Tile::Draw(int xpos, int ypos, SDL_Surface* screen){ Gfx::ApplySurface(xpos, ypos, Gfx::ImageForTileType(_type), screen);}