Well, making a tiled map works something like this:
You have your map data stored in a file that you read in. the file may look something like this: (there is a nice map editor named Tiled to make a file like this, (
http://www.mapeditor.org/))
1 2 3 4 5 6 7 8
|
1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 1
1 0 0 0 0 0 2 1
1 0 0 0 0 0 1 1
1 0 0 0 0 1 1 1
1 3 0 0 1 1 1 1
1 0 0 1 1 1 1 1
1 1 1 1 1 1 1 1
|
Now 1 could be a Wall, 0 could be nothing and 2 could be the goal and 3 could be the spawn point of your Character
You then you read the file in a 2D Map Array with the amount of Tiles in your map and you have the width and height of each block stored somewhere.
Then have a enumeration of Tiles you use (for example: NOTHING, WALL, GOAL, SPAWN)
1 2 3 4 5
|
enum Tile{ NOTHING, WALL, KILL, NTILES };
SDL_Textures (*Textures)[NTILES];
const int TILES_X = 50; const int TILES_Y = 50; //50x50 map
const int TILE_SIZE_X = 32; const int TILE_SIZE_Y = 32; // each block 32x32 pix
Tile MAP[TILES_X][TILES_Y];
|
And since you use SDL you could just make a class for all of the code above to make everything easier and more readable
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
class Tile
{
//// If you split your code in *.cpp and *.h file you should put the members and the enum as far down as possible to make it more beautiful
public:
enum ETile { NOTHING, WALL, KILL, NTILES };
static const int SIZE_X;
static const int SIZE_Y;
private:
static SDL_Texture (*pTextures)[NTILES]; // Array of pointer, point to the textures you want your tiles to look like
SDL_Rect mRenderRect; /// Rectangle you draw to
public:
Tile()
{
mRenderRect.w = SIZE_X; mRenderRect.h = SIZE_Y;
}
void InitTextures()
{
/* Load the Textures you want your tiles to be */
}
ETile tile; // Which tile is this?
void render(int PositionX, int PositionY)
{
mRenderRect.x = PositionX; mRenderRect.y = PositionY;
SDL_Render(mpRenderer, &pTextures[tile], NULL, &DestRect() )
}
};
int Tile::SIZE_X = 32;
int Tile::SIZE_Y = 32;
SDL_Texture (*Tile::pTextures)[NTILES];
// somewhere in main.cpp
const int TILES_X = 50;
const int TILES_Y = 50; //50x50 map
Tile MAP[TILES_X][TILES_Y];
|
Then you will have something like a viewport (mostly the upper left corner of the screen you want to see at the moment and the size)
1 2 3 4 5 6 7 8 9 10 11 12 13
|
template <typename T>
class Vector2
{
public:
T x;
T y;
};
class Viewport
{
public:
Vector2<int> position;
Vector2<int> size;
};
|
And now you just Render all your tiles
1 2 3 4 5 6 7 8 9 10 11 12
|
for(int y = 0; y < TILES_Y; ++y)
for(int x = 0; x < TILES_X; ++x)
{
Vector2<int> position;
position.x = x*Tiles::SIZE_X;
position.y = y*Tiles::SIZE_Y;
if((position.x + Tiles::SIZE_X > Viewport.x &&
position.x - Tiles::SIZE_X < ViewPort.position.x + ViewPort.size.x) &&
(position.y + Tiles::SIZE_Y > Viewport.x &&
position.y - Tiles::SIZE_Y < ViewPort.position.y + ViewPort.size.y)) // check if the Tile is currently visible
MAP[x][y].render(position.x, position.y);
}
|
How to calculate the viewport position is up to you ;)
Note that the amount of memory used here is equal to the amoutn of different tiles you use