Map problem. How to load different maps? (arrays)

Started by
3 comments, last by andy1984 13 years, 6 months ago
Hello,

I didn't really know what to name this thread but I'll try to explain my problem.

Okay I have a map. I draw a certain tile if the array contains certain numbers. For example:


int map[2][2]

//Then the array contains something like this:

0,0
1,0


So when looping through I'd draw an image at the number 1.

Imagine that I have 100 maps. All in a special order that I wanna draw them. When I finish map1. how would I then load the next map? Do I create an array of two dimensional arrays and call them in that way?

Geez, I can't even understand myself.. I basically just want a map system that loads the next map when the first one is finished.
Advertisement
Hello to Sweden. One possibility: Make sure your code has stopped reading from the array and then replace the values in the array from values you read from a file. Then let the simulation continue.

This assumes that the arrays are of the same size.

This can easily be a binary file if you only need an array of numbers like in your example.

If the player wants to go back to an earlier map then you just load its data from a file, as simple as that. There is no need to have all the maps loaded. You will want to store the data in files any ways.

I don't know your programming language but let's assume C++ now.

About loading such an array from a file... something like this:

#include <fstream>// ...// Reserve memory for the array dynamically (you can have a static array// too if you think you know already that the size is always something// specific). Notice how we combine the 2D array into a 1D array here.int* map = new int[2*2];std::ifstream fin( "my_map_file.bin", std::ios_base::in | std::ios_base::binary );if ( fin.is_open() ) {    // we assume here that the file doesn't contain anything else than 2*2 ints    fin.read( (char *)(map), sizeof(int) * 2 * 2 );    if ( !fin.good() ) {        // well, the read operation failed.    }    fin.close();}// ... then you continue with the simulation// until the enddelete[] map;


To load another level you can use the same map int array if it's the same size but if not then you can delete the old one and reserve a new one of the correct size. Or if the size of the array isn't too big* then you can have it as a static array decided at compile time. In the above example the sizes 2 and 2 would not really be hard-coded (unless you want it so!) but maybe load them from your map file too.

If that doesn't help then maybe explain better what you are doing.


* The space, "the stack", reserved for such 'automatic' variables can actually be quite limited and you don't want to blow it up because that would mean your program has crashed. So when you need a big array you need to use 'new' to reserve memory for it from "the heap" and remember to use the array form of delete with the [] to free it up later.

[Edited by - reptor on October 17, 2010 6:13:42 PM]
Thanks for your reply.

All maps are [24][32]. It's always that way.

I'm not very familiar with the ifstream although I've encountered it before. But how would I loop through that file; to check on which integer it encounters? And why a .bin file?

When "converting" the array into a single one [24*32] I also had problems with my nested for loops, even if the map array was declared in the code. I didn't really know how to calculate. In a two-dimensional case it would be:

for(int i=0;i<24;i++)

for(intj=0;j<32;j++)

if(map[j] = 1) draw this
if(map[j] = 2) draw that

Yea you problaby know the procedure

how is it with a single array?

if(map[i*j] = 1) draw this? I sense that such will do some crazy stuff :)
"how would I loop through that file"

This http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.16 is a good page to read. It has some examples on how to do it. I think the examples on that page should get you further with this.


"And why a .bin file?"

The extension does not matter - I just made something up. If you meant why a binary file - because it's more efficient. I don't see why you should be parsing through a text file to get such an array of numbers - I think it's easier to store them in a binary file. As you can see from the example the code to load the array of integers is really simple. Saving is simple too.

Of course editing the contents of the file this way is more difficult - it is up to you to decide how you want it. Writing a program to take a text file containing the array and converting it into a binary file containing the array could be a good exercise for you in fact.

I think your array is so small that you don't need to use 'new' to reserve memory for it. You can just define the size of it at compile-time and that should work fine. So you can have one array for which memory is always reserved irrespective of which map is loaded and you just overwrite its contents when you want to change the map.
Quote:Original post by n1rium
if(map[i*j] = 1) draw this? I sense that such will do some crazy stuff :)


With a single dimension array its always
array[y * width + x]
to access a cell. You do use [width * height] when you initialize the array.

I'm assuming you want to load multiple maps in one file?

std::ifstream in(filename.c_str(), std::ios::in);if (!in.good())    return;int nMaps;in >> nMaps;int *maps[nMaps];for (int n = 0;n < nMaps;n++){    int w, h;    in >> w >> h;    maps[n] = new int[w * h];    for (int y = 0;y < h;y++)    {        for(int x = 0;x < w;x++)        {            in >> maps[n][y * w + x];        }    }}


Typically however I would do something like:

class Map{    int w, h;    int* cells;    void resize(int w_, int h_)    {        w = w_;        h = h_;        cells = new int[w * h];    };    void readFromFile(std::ifstream& in)    {        // read w, h, cells    };}class Maps{    Map* maps;    int numMaps;    bool loadFromFile(std::string filename)    {        // open file        // read maps size, etc.        // make array        // loop to read in maps    };}

This topic is closed to new replies.

Advertisement