The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
C++ with SDL, help on how to create a 2D map
xtheseven


Joined: 17 Aug 2013
Posts: 3
Hey guys,

I'll begin by telling you exactly what I'm doing and then telling what kind of help I need.

What I'm doing:
I've been learning C++ and I've been learning how to do a text-based RPG game. It's something simple, you have a storyline to follow, classes, NPC's to talk to, combat system, menu system, equipping items system, etc etc.

- I have a fair knowledge of C++;
- I don't know how to, like, do checkpoints through I/O files (i think that's the correct term, forgive me if not).
- I've just begun learning SDL through Lazy Foo's tutorials, currently using 1.2

What I want help with:
In that game, I want to have a simple 2D map that will help the player to know where he/she is to make the game much less confusing. This map will appear above the text and I want it to change as the player advances in the game, like:

Code:
|___|
| o |
|___|
(Player Location is "o")

You wake up in the middle of a forest bla bla bla a path goes North.
1: Go north

(player presses 1)

Code:
|   |
|___|
| o |
|___|
|   |
|___|


bla bla bla bla the path continues to the north.
1: Go north

Get it?
Now I want to do this with SDL to make it easier so i don't have to build the map in C++ everytime I write a new area.

How can you help me:

I need a good tutorial (text or video, it's indifferent) that explains me how to build this kind of map for this purpose in SDL.

Does anyone know such a thing?
Can I learn how to do this by simply learning SDL?
Is there any other (preferrably simpler) way of doing this?

Thank you so much in advance.
mars1990


Joined: 21 Aug 2013
Posts: 10
Location: Poland
Hi,
You prefer to keep it text-based or not? If yes, I think that SDL should be used only for event handling, etc.. What you need is a plain-text file, that's filled with some data (map). You could read that file and, depending on the character's x and y position, output proper part. In game you could store it in 2D array or vector of vectors. But if you want to put some graphics, then you need to write few more lines, specify which image corresponds to certain value in the map file and then render it, again according to player's position. I'm working on tile-based game engine right now. Nothing special since I'm not that skilled. But that's why I'm trying to make it. To get that skill Smile

Here's the screen from the map editor. Long loading time due to 144 layers (stored in 24 areas within 1 map) of which 48 were storing 1000x1000 arrays (just to see performance). When I made all layers 50x50, the loading time of 144 of such layers got down to 0.3 s.


And here a window of the early game state (yes, I like pokemons! Very Happy):


If you're interested in some hints just let me know Smile
xtheseven


Joined: 17 Aug 2013
Posts: 3
well I'd like to keep it text-based, my initial Idea was to do a simple, static map that would change only when the player mkoved to another location using SDL, even if I, like, had to do multiple images and then call 1 for each location, and use TTF to write the text part but i think that handling all the game events with SDL would be a bit complicated, at least for now, can you give me hints on how to do the text file thingy?
mars1990


Joined: 21 Aug 2013
Posts: 10
Location: Poland
Let say we have a file filled with map data that follows this pattern:
Code:
11111
10001
10001
10001
11111


The map itself can be whatever size you like and contain any ASCII character. For simplicity, let just assume we have fixed size of 20x20. Then we can load it and store using code like this:
Code:
ifstream inputFile("map.txt");
string line;
char ch;

char **layer;
layer = 0;
int height = 20;
int width = 20;

// create dynamic array
layer = new int *[height];
for(int i = 0; i < height; i++)
   layer[i] = new int[width]();

// populate array with values from file
for(int h = 0; h < height; h++)
{
   std::getline(inputFile, line);
   istringstream sT(line);
   for(int w = 0; w < width; w++)
   {
      if(!sT.eof())
      {
         sT >> ch;
         layer[h][w] = ch;
      }
   }
}


Maybe it's not elegant, but it's not supposed to handle space shuttle control so it's relatively fine.
Then the drawing routine. Assume now a player, consisting of two variables x and y (SLD_Point would be enough for this). So we call it like that:

Code:
for(int row = player.y - 5; row < player.y + 6; row++)
{
   for(int col = player.x - 5; col < player.x + 6; col++)
   {
      if(row == player.y && col == player.x)
         cout << "X";
      else
         cout << layer[row][col];
   }
   cout << endl;
}


You can do it 100000x better, faster (stronger!), but the main advantage is: for small projects it works fine and is simple;
The code might have some bugs since I had to rewrite some of the components in the reply window, but if you encounter any problem while implementing and cannot solve it, feel free to ask Smile
xtheseven


Joined: 17 Aug 2013
Posts: 3
that's already a great help, i don't understand some things from the first block of code but it's normal because i don't have any knowledge about managing files in c++ but it still helps a lot, thank you Very Happy
mars1990


Joined: 21 Aug 2013
Posts: 10
Location: Poland
This should help:
http://www.codeproject.com/Articles/21909/Introduction-to-dynamic-two-dimensional-arrays-in

And some comments:
ifstream inputFile("map.txt"); - input file stream, opens file and lets us read it (read more: http://www.cplusplus.com/reference/fstream/ifstream/ ).
**layer; - pointer of pointers (see 1st link), 2D array for our map (sorry for the name "layer", think of it as "map").
layer = new int *[height]; - create dynamic 1D array. Dynamic because we don't have to specify it's size at this moment.
for(int i = 0; i < height; i++)
layer[i] = new int[width]();
- fill the above array with 1D dynamic arrays of zeros(parenthesis at the end initializes content to the specific value of the type used. We use int, so whole array will be initialized to 0 since it is int's default value). This leads us to an 1D array of 1D arrays, thus being a 2D array.
for(int h = 0; h < height; h++) - iterate through rows.
std::getline(inputFile, line); - read line from file and send output to variable "line".
istringstream sT(line) - this allows us to split line into separate characters.
for(int w = 0; w < width; w++) - iterate through columns.
if(!sT.eof()) - check if we get to the end of file. If not...
sT >> ch; - pass one character to ch variable
layer[h][w] = ch; - set obtained character in the proper place in our array