The 'equivalent' of a 2d array for a vector of vector is something like this:
std::vector<std::vector<int>> mTileMap;
You can add values to it like this:
int numRows = 4;
int numCols = 6;
for ( int y = 0; y < numRows; ++y ){
mTileMap.push_back( std::vector<int>() );
for ( int x = 0; x < numCols; ++x ){
mTileMap[y].push_back( /* your tile will be added here*/ );
}
}
You can use that method if all the values for the map are different.
A simpler way to only allocate your map would be to tell it the sizes at construction:
int defaultTileValue = 0;
std::vector<std::vector<int>> mTileMap( numRows,
std::vector<int>( numCols, defaultTileValue ) );
or
mTileMap = std::vector<std::vector<int>>( numRows,
std::vector<int>( numCols, defaultTileValue ) );
With that method, you lose the possibility to set a specific value for each tile. You can use the iteration methods described below to do that.
And you access it this way:
for ( int y = 0; y < mTileMap.size(); ++y ) {
for ( int x = 0; x < mTileMap[y].size(); ++x ) {
std::cout <<
"TileMap value at row " << y <<
" column " << x <<
" is " << mTileMap[y][x] << "\n";
}
}
If you want to use iterators, you can get go through each element like this:
for ( auto& itRow : mTileMap )
{
for ( auto& itCol : itRow )
{
std::cout << "TileMap value is " << itCol << "\n";
}
}
The iterator version allows you to go through each element, but you lose the concept of 'index' for your x and y. It's ok for some situations, but for some other situations, an iterator won't do and you'll have to use the first version.
Note that the above is a very naive way to create and use a 2d vector. It works and it is easy to understand, but it's not very efficient, specially if the data is to be used and iterated over often.
You might be interested in a single vector that contains all your data.
// In header
const int numRows = 4;
const int numCols = 6;
int getFlatVectorIndex( int aIndexX, int aIndexY ) { return ( numCols * aIndexY ) + aIndexX;}
std::vector<int> mTileMap;
// This is the initialization code:
mTileMap.resize( numRows * numCols );
for ( int y = 0; y < numRows; ++y ){
for ( int x = 0; x < numCols; ++x ){
mTileMap[getFlatVectorIndex( x, y )] = /* your tile will be set or accessed here */;
}
}
The reason why this implementation is better is because all your data are close together in memory, allowing you to benefit from Data Locality.
Disclaimer: I don't have access to my compiler to make sure this works for now.