C++ doesn't support 2D arrays directly in the language,
unless the sizes of both dimensions are known at compile-time. For dynamically-sized 2D arrays you sort of have to "fake it" using an array of arrays, or a 1D array where you calculate the array index from your two "2D" indices. I think there might be a way to make this prettier via operator overloading, but it's been a while...
First, I will explain why the compiler is complaining (you learn a lot by understanding compiler diagnostics):
Code: Select all
// You can't do this because m_width and m_height are variables.
// The syntax you're using is telling the compiler to create a fixed-size
// 2D array on the stack, but it can't be fixed-size because m_width
// and m_height are variables.
// Also, I hope you have a default constructor defined for Tile, because
// this is declared as an array of Tile objects, not pointers to Tile
// objects.
Tile tiles[m_width][m_height];
for(int x = 0; x < m_width; x++)
for(int y = 0; y < m_height; y++)
{
// I don't see the variable "tile" declared anywhere. I hope it's
// a Tile*, because otherwise this won't work.
tile = new Tile(x,y,TileType::Grass);
}
// You can't take the address of a type. If you meant &tiles, that's
// a fairly dangerous thing to do because stack-allocated objects
// disappear as soon as the function in which they are declared exits.
m_tiles = &Tile;
For the array of arrays approach, try this (warning: I haven't tried compiling it, so there may be a little error or two):
Code: Select all
// Assuming that m_width and m_height are both of type int, and
// that m_tiles is of type Tile***. There are three stars because
// it is a 2D array of pointers to Tile objects.
m_tiles = new Tile**[m_width]; // Create the array of arrays.
for(int x = 0; x < m_width; x++)
{
m_tiles[x] = new Tile*[m_height]; // Create each "column"
for(int y = 0; y < m_height; y++)
{
// This is why m_tiles must be Tile*** -- because operator new
// returns a Tile*, not a Tile.
m_tiles[x][y] = new Tile( x, y, TileType::Grass );
}
}
Don't forget to delete everything when you're done with it. If you're doing this all manually just to learn the language, that's fine, but in reality a better way to do this would be to use STL vectors (this code is also untested):
Code: Select all
// Assuming that m_width and m_height are both of type int, and
// that m_tiles is of type std::vector< std::vector<Tile*> >.
// You can also construct it to be the right size if you use an
// initialization list in your constructor.
m_tiles.resize( m_width ); // This creates each "column" for you.
for(int x = 0; x < m_width; x++)
{
for(int y = 0; y < m_height; y++)
{
m_tiles[x].push_back( new Tile( x, y, TileType::Grass ) );
}
}
You still need to delete each Tile in the vector-of-vectors when you're done using it, however. But it's a lot less to clean up than when using plain arrays.