Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am writing in C++. I am storing game levels as a 2-dimensional int array. This may be a hacky way of doing things, but I am not ready to change it unless I have to. I store values in the array and then draw them as I read the array. These are constant for me but I need to access them from multiple files.

How can I do this? If I put the level arrays in a header (.h) file and include it in many places I get a redefined variable compilation error. Is there a way to define a variable so it can't be used more than once?

How can I go about this in a better way?

share|improve this question
4  
Sounds like a question for Stack Overflow. –  Byte56 Dec 27 '12 at 23:07
4  
Shouldn't you just reference to one object that holds the level array? –  Sidar Dec 27 '12 at 23:28
2  
The redefinition error is not really anything to do with level storage and more about a misunderstanding of how header files and the compilation process works. I wrote an article on such things many moons ago, which some find helpful. gamedev.net/page/resources/_/technical/general-programming/… –  Kylotan Dec 28 '12 at 2:06
add comment

3 Answers

up vote 6 down vote accepted

If you want a variable visible across multiple files, use extern:

// Globals.h
extern int Data[10][10];

//Globals.cpp
int Data[10][10];

However, it makes a lot more sense to load them from file. Even if you don't want to use standard library containers, loading and saving is trivial, and will help you to modify and add additional levels in the future. Also note that you will be able to supply an editor for maps.

Here's sample 2-dimensional C-style array serialization:

#include <fstream>

int Data[SizeX][SizeY];

// save
{
    // You can use binary mode too!
    ofstream File ("data.txt");
    for (unsigned y = 0; y < SizeY; ++y)
        for (unsigned x = 0; x < SizeX ++x)
            // you'd need to change it to File.write(...) when using binary mode.
            File << Data[x][y] << " "; 
}
// load
{
    ifstream File ("data.txt");
    for (unsigned y = 0; y < SizeY; ++y)
        for (unsigned x = 0; x < SizeX ++x)
            File >> Data[x][y];
} 

You might also want to add some sort of header to your file - containing map size, game version, author of the level etc. However, loading of this data is trivial and I leave it as an exercise :)

I'd also take a look at std::vector. Contrary to your belief, it's a lot easier to use than C-style arrays. It was designed to be!

share|improve this answer
    
+1, lots of good stuff packed into this answer. –  Seth Battin Jul 17 '13 at 21:56
add comment

I made a tile based breakout game, and stored the levels in 1 txt file. 0 was no block, and a 1-9 was a block that would take that many hits. I suppose it could be expanded to use letters as powerups or special block. But they were formatted to be a certain width, and a certain length, with 1 line between each level.

ex

11111
00000
00010
11101

11001
02223
12321
11111
share|improve this answer
    
+1 for coupling binary efficiency with ascii simplicity. What about whitespaces, though? –  Bartek Banachewicz Dec 28 '12 at 13:34
    
The white space is the end of the last level, start or the next. The code parses the whole thing as an array starting from zero till the end of level one. Then start from zero + llevel count + 1 for the next level. It doest need the space, just makes it easier to read. –  ProtoJazz Dec 28 '12 at 20:46
    
I meant more "what about accidental whitespace addition, if the user tries to edit the file by hand, for example?" –  Bartek Banachewicz Dec 29 '12 at 11:59
    
You could ONLY edit the file by hand. But your right, God help you if you add a blank line in somewhere, it wouldn't break anything but it would throw off all levels by 1 line –  ProtoJazz Dec 29 '12 at 13:10
1  
Yeah, you could probably write a small function that would clean the level file, remove unexpected line breaks and So on. If you know hoes it supposed to be youcan form whatever is there into format –  ProtoJazz Dec 29 '12 at 15:46
show 1 more comment

Unfortunately no, you can't define multiple variables with the same name. Suppose the compiler lets you do so, but when you're going to use it, how do you know which one are you talking about?

So in general you have three choices:

  1. Make each level into a different variable. Instead of int[] level, do int[] level1, int[] level2 and so on. It's the easiest to understand, but scales the worst, as you have to hardcode everything, and will get bored writing everything as you reach more levels.

  2. Make them into an array. Instead of int[] level, do int[][] levels, and store the first level in levels[0], the second one in levels[1] and so on. You can either initialize them statically in a single huge file, or dynamically with a bunch of files.

  3. Make your levels load dynamically from data files. This is what professional games do, and is a very positive thing because you're separating code from data. So you keep your int[] level, but initialize it by reading a bunch of ints from a file. Google "reading ints from a file c++" for more information on how to do this.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.