SFML community forums

Help => Graphics => Topic started by: game_maker on July 09, 2012, 05:32:09 pm

Title: Loading a map from text file
Post by: game_maker on July 09, 2012, 05:32:09 pm
I want to load a map from text tile, but the coordinates are not aligned to a grid. So, a map of tiles is not useful for me. I write, in a text file (manually), the positions of the sprites.

Something like this:

name:path:x:y
sprite1:resources\sprite1.png:25:24

So I load:

while(reading)
{
std::string line;
std::string p[4];

getline(..., line)

split(line, ':', &p); //in this case I'll create a method to do this

add p[0] and p[1] to a map (<string, string>)  and return the id of the created texture
create a sprite (sf::Sprite name(id_created_texture))
set the position of the sprite to (p[2], p[3])
}
 

ps: the above is a draft of what I do.

I want to receive tips for making it.

Thanks in advance!
Title: Re: Loading a map of a file
Post by: Tresky on July 09, 2012, 10:19:57 pm
If you are trying to do this for a game you are making, and you don't care if EVERYTHING is made by your fingers, I would suggest making your maps with Tiled Map Editor (http://www.mapeditor.org/).
It is extremely easy to use and their is a library that loads the map directly into your program. All you have to do is change that information into SFML Textures and Sprites.
TMXParser (http://code.google.com/p/tmx-parser/)
Title: Re: Loading a map of a file
Post by: game_maker on July 09, 2012, 10:29:14 pm
I found a tutorial explaining how to load from XML.
I'm trying to adapt it to the SFML 2.0.
I got it, but I want to load from txt.
Title: Re: Loading a map of a file
Post by: Tresky on July 09, 2012, 10:42:25 pm
Okay well then open the text file and using a for loop, cycle through each line. Save one line at a time inside of a std::string and then us another for loop to go character by character and, depending on the character, save a specific image into a vector.

for (int row = 0; file.good(); ++row) {
    std::string line;
    getline(file, line);
    for (int col = 0; col < line.length(); ++col) {
        if (line[col] == '1') {
            // save image for ID of 1
        }
        // .... so on and so forth
    }
}
Title: Re: Loading a map of a file
Post by: game_maker on July 09, 2012, 11:55:19 pm
Yes, I made (did) like this.  :)
It is almost done.

Thank you!
Title: Re: Loading a map of a file
Post by: mastodona7x on July 12, 2012, 12:20:14 pm
I did this for a simple battleships type game and yeh just a for loop to go through the txt file, though I used a "switch" statement instead of lots of if statements, seemed neater somehow but same end result!

for (int row = 0; file.good(); ++row) {
    std::string line;
    getline(file, line);
    for (int col = 0; col < line.length(); ++col) {

switch(line[col])
{
case '1':
            // save image for ID of 1
break;
case '2':
            // save image for ID of 2
break;
}
        // .... so on and so forth
    }
}
Title: Re: Loading a map of a file
Post by: game_maker on July 12, 2012, 11:45:10 pm
Can you help me?

My project: https://dl.dropbox.com/u/38888521/sfml.zip

I am getting errors, so I can't make it work.

At the beginning, it freezes.

Goodbye!
Title: Re: Loading a map of a file
Post by: mastodona7x on July 13, 2012, 12:05:47 am
I can't even get it to compile never mind freeze? Im so new to C++ I could be wrong here but why are you making line a string then using [] on it? Wouldn't it be better to make it a vector and push each item in to that?

ifstream In("data.dat");
    vector v;

    cout << endl << "Read data from file" << endl;
    while ( ! In.eof() )
    {
       getline (In, str);
       v.push_back(str);
    }


the compile error I get is:

imageManager.LoadImage(line[col], id);

1>Level.cpp(97): error C2664: 'ImageManager::LoadImage' : cannot convert parameter 1 from 'char' to 'const std::string &'
1>          Reason: cannot convert from 'char' to 'const std::string'
1>          No constructor could take the source type, or constructor overload resolution was ambiguous
Title: Re: Loading a map of a file
Post by: Tresky on July 13, 2012, 04:47:32 am
Quote
why are you making line a string then using [] on it?
A string is simply an array of characters, so using [] on it will access a specific character inside of it.

string line = "abcde";
line[2] will return 'c'.
line[4] will return 'e'.
etc.

The format of his map is a string of numbers (each number represents one tile on a tilemap). If he accesses each number individually he will be able to then display each tile individually and thereby creating his map.
Make sense?

Quote
Can you help me?

My project: https://dl.dropbox.com/u/38888521/sfml.zip

I am getting errors, so I can't make it work.

At the beginning, it freezes.

Goodbye!
No body is going to want to download your entire project and go through your entire code. Make a reduced code that still presents the error. Then C/P that code into here.
Title: Re: Loading a map of a file
Post by: mastodona7x on July 13, 2012, 11:34:42 am
Well for some reason the function he passes the string[] in to sees the string[] as a char and not a string so it won't compile...
Title: Re: Loading a map of a file
Post by: game_maker on July 13, 2012, 09:52:24 pm
Now I am making a level editor from scratch (based in others).

Thanks
Title: Re: Loading a map of a file
Post by: Tresky on July 13, 2012, 10:07:53 pm
Quote
Well for some reason the function he passes the string[] in to sees the string[] as a char and not a string so it won't compile...
I see what you're saying. Allow me to explain. A std::string is nothing more than a character array. Therefore using the brackets on a string is simply accessing a specific element in the character array.

std::string line = "Tresky";
line[0] will return 'T'
line[2] will return 'e'
etc.
Title: Re: Loading a map of a file
Post by: game_maker on July 14, 2012, 01:45:20 am
If I create a method:

MyMethod (char *);

And I use the code:

std::string A;
MyMethod (A);


Will generate errors?


Title: Re: Loading a map of a file
Post by: eXpl0it3r on July 14, 2012, 02:16:55 am
If I create a method:
MyMethod (char *);
And I use the code:
std::string A;
MyMethod (A);
Will generate errors?
If you take your time to write this post, why didn't you just test it?
Also this is a basic C++, read a book about it.

Yes of course it will generate an error since: std::string (class) is not the same type as char * (pointer to a char).
And don't use char * that's old C code and perfect for stack overflows, crashes and other security risks.

@mastodona7x: You are aware that there are code=cpp tags to use? Please use it...
Title: Re: Loading a map of a file
Post by: game_maker on July 14, 2012, 02:45:10 am
Sorry, I posted the wrong thing.

The correct:

If I create a method:
MyMethod (char []);
And I use the code:
std::string A;
MyMethod (A);
Will generate errors?
Title: Re: Loading a map of a file
Post by: eXpl0it3r on July 14, 2012, 02:48:32 am
Sorry, I posted the wrong thing.

The correct:

If I create a method:
MyMethod (char []);
And I use the code:
std::string A;
MyMethod (A);
Will generate errors?
If you take your time to write this post (twice), why didn't you just test it?
Also this is a basic C++, read a book about it.

Yes of course it will generate an error since: std::string (class) is not the same type as char [] (an array of char, which is equal to char *).
And don't use char[] that's old C code and perfect for stack overflows, crashes and other security risks.

Just use a std::string unless you have a reason not to.
Title: Re: Loading a map of a file
Post by: game_maker on July 14, 2012, 03:07:20 am
eXpl0it3r, I heard that std :: string is equal to an array of chars. I believe in you, but can you explain it?

Furthermore, there are functions (fstream library) using const char * std. Can I use std::string as parameter?
Title: Re: Loading a map of a file
Post by: eXpl0it3r on July 14, 2012, 03:24:44 am
What you've probably read, is that a C string is equal to char */char []. But a C string is not a std::string. A C string is just an array of chars with null delimiter \0 at the end, thus it has no function or anything, it's just data. The std::string is a class defined in the STL and has diffrent functions. One of which is .str() which returns a C string.

This is basic C/C++ knowledge you should defenetly read more about it.
Title: Re: Loading a map of a file
Post by: game_maker on July 14, 2012, 08:13:05 am
Thanks.

Can anyone give me an idea of ​​how to save / load a map with objects in different positions (not aligned to a grid)? I am spending much time on this.
Title: Re: Loading a map of a file
Post by: mastodona7x on July 14, 2012, 02:35:54 pm
game_maker I have very little knowledge of c++/sfml but one of the first games I made was a battelships game, which is the same sort of idea.

I made a vector<vector> for the map and that stored values for different things at each coordinate (0,4 might have had a value of "2" for example which translated to part of a ship, or value of 1 for open water, etc...then just loop through the vector to output whatever each value translates to to the screen, similar to how you've been doing.

for example:
Code: [Select]
//create empty map array
vector<vector<int>> player1map; // create 2d vector (matrix)

 // map array size xsize * ysize filled with 0's
        player1map.resize(xsize, vector<int>(ysize,0));

the above makes a vector of ints and xsize and ysize are the x and y size for the grid (might be 10*10 for example), first it fills them with 0's but you can obviously do what you like there,

Code: [Select]
for(int y=0; y<ysize; y++) // y-wise (number of rows)
    {

for(int x=0; x<xsize; x++) // fill in x-wise
        {
            switch (maparray[x][y])
{
case 0: // fill "square" with empty space / water
///display empty water graphic here
break;
                         }
         }
   }


Its very basic and not reading from files etc but maybe it'll give you something to work with I don't know.
Title: Re: Loading a map of a file
Post by: mastodona7x on July 14, 2012, 02:39:07 pm
I just realised my above post really doesn't answer your question but maybe instead of worrying about loading/saving just work out some more basic ways to do things if you are just begginning like I am? Don't try to walk before you can crawl sort of thing :) Make a basic grid based game to start with then build on what you have learned.
Title: Re: Loading a map of a file
Post by: eXpl0it3r on July 14, 2012, 03:54:26 pm
@mastodona7x: Now you just need to write code=cpp instead of just code to get a code tag that highlights C++ code! ;)

Can anyone give me an idea of ​​how to save / load a map with objects in different positions (not aligned to a grid)? I am spending much time on this.
How does your game look like up to now? Because having objects with their own positions, probably requires something into the direction of an entity system.
For now I just assume that you have a st::map<std::string, sf::Sprite> that you will fill with sprites and use a key to access them more easily.
For a start you have to think about how your map format will look like. I could imagine something like this:
name:path/to/the/texture.png:10:20
This means each line starts with the name of the sprite/character/whatever that will end up as key, then we use a delimited ':' to seperate the diffrent properties. Next to the name you put the path to the texture that should be used for the sprite and the the position as x and y coordination.

Now you have to read that file line by line (code can be found earlier on this thread) and then split each line into it's individual parts. For that you can easily google "split string c++". And since you now have everything as string you'll have to convert the numbers into real numbers (int, float...), this can also be found easily with google. But keep in mind google is only a help to find a solution fast, to really understand it you'll have to figure it out on your own, or at least try to understand every step of the code you'd find.
Since you now have everything you need, you can just go ahead and create a new texture, load it from the provided path, then hand the texture over to the new sprite and set its position.

In the following pastie (http://pastebin.com/1HxUnzBj) you can find a solution that I've used in one of my application. I may have missed some variables when copying. This solution is only one way of doing things, for example I don't use a std::map to hold my sprites as suggested. Also the use of std::move isn't always appropriate, so don't use it if you don't know what you're doing.
Title: Re: Loading a map of a file
Post by: game_maker on July 14, 2012, 05:28:52 pm
eXpl0it3r, thank you so much.

I can read the file line by line, dividing lines (split).

The problem now is to convert the "20" to 20. I think to use atoi, but I'll need the function c_str (), will not I?

Edit:

Now I saw your code at pastebin.
It was very helpful and I will try to take only the concepts.
Since I'm redoing this from scratch, I'm reviewing some things.

Thanks in advance!