Sign in to follow this  
mcphist

Array Map

Recommended Posts

Hi all. I made a snake game, but I have a question about how to desing levels. I see that most people makes an array map [ROWS][COLUMNS]. COLUMNS = WIDTH OF MAP / WIDTH OF TILE ROWS = HEIGHT OF MAP / HEIGHT OF TILE But in my case i don't have tiles, it's a pure console game. In console full screen mode, I have a window of 80x50. Should i have to do then an array of 80x50??? I think that's very ugly. Thanks in advance!! Sorry my poor english :)

Share this post


Link to post
Share on other sites
Assuming that you are talking about a map of walls and stuff on the level, I don't see what is ugly about that. Since the size will also be fixed, I don't even see any major issues with using a dreaded two dimensional array either.

The only other option would be to store the wall segments in some kind of list and iterate through this list when you draw the screen or test for collisions which, while possibly taking up slightly less space, would incur far more inefficiency than creating an 80x50 array would.

It is quite common to create massively bigger arrays than that to store the maps for 2D games. You do have tiles in a way, they are just fixed at the size of a console character at that particular resolution. Apart from that, there is no real difference from any other kind of tile-based 2D map.

In what way do you find it ugly? I don't really understand that part.

Share this post


Link to post
Share on other sites
Thanks for the reply man. Well, i have search in a lot of examples and i didnt see anyone with such a big array like mine.

Isn't problem then declaring an map array like this?

MAP[80][50] = {
11111111111111111111111 .... until 80
1
1
1
until 50}

Share this post


Link to post
Share on other sites
Quote:
Original post by mcphist
Thanks for the reply man. Well, i have search in a lot of examples and i didnt see anyone with such a big array like mine.

Isn't problem then declaring an map array like this?

MAP[80][50] = {
11111111111111111111111 .... until 80
1
1
1
until 50}


A 80x50 byte array is quite small, so it is absolutly no problem to use a map of this size.

1. Try to create your level in the source code first.

char MAP[80][50] =
{
{1,1,1,1,1,1,1,1,1,1,1,1,1}, // first line
{1,0,0,0,0,0,0,0,0,0,0,0,1}, // second line
..
// until 50
}



2. To improve it, try to read/write your map from/to a text file.

--
Ashaman

Share this post


Link to post
Share on other sites
[EDIT - Started writing this post before Ashaman replied]

Oh right. Ugly. See what you mean.

The obvious suggestion would be to not hard code the map, but load it from a text file at startup instead. This has the clear advantage that you can change the level without recompiling, and even have different levels in different files:


int Map[80][50];

bool LoadMap()
{
std::ifstream is("map.txt"); if(is.fail()) return false;

for(int Y=0;Y<50;++Y)
{
for(int X=0;X<80;++X)
{
is >> Map[X][Y];
}
}

return true;
}








map.txt

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 // etc
1 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0 1 1 1 // etc
//etc








It would be quite unusual to hard code a map into the program in anything but the most basic or trivial games.

PS: I might have got the order of my X and Y muddled in the array declaration and loading. I can never get my head straight with built-in multidimensional arrays.

I'd always prefer to wrap a std::vector in a Map class for this sort of thing. It means you could resize the map at runtime (not a problem in this project, I know) and pass it around functions much more easily and flexibly:


class Map
{
private:
std::vector<int> v; int wt,ht; // width and height

public:
Map() : wt(0),ht(0) { }
Map(int w,int h) : v(w*h),wt(w),ht(h) { }

int &operator()(int x,int y);

int width() const { return wt; }
int height() const { return ht; }

void resize(int w,int h){ wt=w; ht=h; v.resize(w*h); }
};

int &Map::operator()(int x,int y)
{
if(x<0 || x>=wt || y<0 || y>=ht) throw AnError();
return v[(y*wt)+x];
}

Map M;

bool LoadMap()
{
std::ifstream is("map.txt"); if(is.fail()) return false;

int W,H;

is >> W >> H; // map.txt prefixes the tile info with the width and height

M.resize(W,H);

for(int Y=0;Y<M.height();++Y)
{
for(int X=0;X<M.width();++X)
{
is >> M(X,Y);
}
}

return true;
}

void f()
{
M(2,3)=34;

if(M(5,4)==5) std::cout << "yupsters\n";
}




Share this post


Link to post
Share on other sites
Quote:

A 80x50 byte array is quite small, so it is absolutly no problem to use a map of this size.

Yeah, isn't a big array in memory, but it seemed to me unusual for a map.

Quote:

The obvious suggestion would be to not hard code the map, but load it from a text file at startup instead.

Yes, in fact, I'll load the maps from a text file, but for testing I have to hard-coded.

Quote:

I'd always prefer to wrap a std::vector in a Map class for this sort of thing. It means you could resize the map at runtime (not a problem in this project, I know) and pass it around functions much more easily and flexibly

Yeah, i think that I'll use a vector.

Thanks to both!

Share this post


Link to post
Share on other sites
I prefer loading my maps from code, however it does look messy so I use

#region
#endregion

For those parts to make them less noticeable. I'm still learning Array Maps from text files though. Even though this tutorial is based on XNA the basic concepts should help you understand Array Maps, it worked for me.

http://www.xnaresources.com/pages.asp?pageid=7

Share this post


Link to post
Share on other sites
Quote:
Original post by Jettoz
I prefer loading my maps from code, however it does look messy so I use

#region
#endregion

For those parts to make them less noticeable.


I'm pretty sure that's either compiler- or language- specific.

As for the vector usage, you can probably do even better for a 2D map: please investigate boost::multi_array. (The native C and C++ arrays are really quite evil; they should only be used in the simplest circumstances in which they do everything that's actually needed.)

Share this post


Link to post
Share on other sites
#region
#endregion

This is an option within the Visual Studio 2005 or Express Compilers to tab a large or small amount of code. All code made within Visual Studio can use that command.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this