Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Hopefully my last map-related question.

This thread is locked; no one can reply to it. rss feed Print
Hopefully my last map-related question.
valentino
Member #8,853
July 2007

Whenever I load my txt, it doesn't seem to be drawing tiles in the proper locations. For example (in my case) tile 4 is where tile 2 should be and vice versa. What am I doing wrong?

// The map loading function

void LoadMap(const string& filename) 
{    
  ifstream file; 
  file.open(("data/"+filename+".txt").c_str(), ios::in); 
  for(x = 0; x < MAP_W; x++) 
    for(y = 0; y < MAP_H; y++)
      file >> mMapArray[x][y];
  file.close();
}

// Drawing the map

  for(x = 0; x < MAP_W; x++) 
    for(y = 0; y < MAP_H; y++)
      mTile[mMapArray[x][y]]->Draw(...)

This is how my txt looks.

6 2 2 2 2 2 2 2 2 7 
4 1 1 1 1 1 1 1 1 5 
4 1 1 1 1 1 1 1 1 5 
4 1 1 1 1 1 1 1 1 5 
4 1 1 1 1 1 1 1 1 5 
4 1 1 1 1 1 1 1 1 5 
4 1 1 1 1 1 1 1 1 5 
4 1 1 1 1 1 1 1 1 5 
4 1 1 1 1 1 1 1 1 5 
8 3 3 3 3 3 3 3 3 9

And this is how it's displaying it.

6 4 4 4 4 4 4 4 4 8
2 1 1 1 1 1 1 1 1 2 
2 1 1 1 1 1 1 1 1 2 
2 1 1 1 1 1 1 1 1 2 
2 1 1 1 1 1 1 1 1 2 
2 1 1 1 1 1 1 1 1 2 
2 1 1 1 1 1 1 1 1 2 
2 1 1 1 1 1 1 1 1 2 
2 1 1 1 1 1 1 1 1 2 
7 5 5 5 5 5 5 5 5 9

Jonatan Hedborg
Member #4,886
July 2004
avatar

That's because you are reading it in the wrong order. Since you have for(x) outer and for(y) inner, it reads the data column-wise instead of row-wise. Just switch the for's and you'll be fine.

Matthew Leverton
Supreme Loser
January 1999
avatar

Also it's generally better to store maps in (y,x) since you'll naturally want to access them rows at a time.

valentino
Member #8,853
July 2007

Oh.. I always thought it goes x then y. Thanks!

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

One thing I notice is :

  for(x = 0; x < MAP_W; x++) 
    for(y = 0; y < MAP_H; y++)
      mTile[mMapArray[x][y]->Draw(...)

Probably a typo , but mMapArray probably isn't a pointer and the data not pointed to by it doesn't have a member named Draw does it? (Missing square bracket)
Shouldn't it be :
(mTile[ mMapArray[x][y] ])->Draw(...)

Global variables can screw things up when you go to modify your program. I try to make all my functions autonomous by passing them all the information they need or making them capable of getting it themselves.

In LoadMap the line :
file >> mMapArray[x][y];

What data type is mMapArray? Is it integer?

The extraction operator '>>' can be a little tricky. Check out 'manipulators' at this page on operator>>

valentino
Member #8,853
July 2007

(Edited)

Oops, I forgot to put the other ]. mTile is a "BITMAP" pointer and mMapArray is an int.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Did Jonatan and Matthew's advice fix all your problems?

Is this line psuedo-code? BITMAP objects don't have any methods named Draw.
mTile[mMapArray[x][y]]->Draw(...)

Is mTile a pointer to a bitmap pointer? (BITMAP**)
What is your drawing code?

valentino
Member #8,853
July 2007

Yup all fixed up. And yes it is, it's not a BITMAP, just sorta like one. I was wondering how I can handle layers without having to make a bunch of different arrays. This is the code I'm currently using for my map, found recently. If it can be altered to accommodate layers that would be great, because I want to keep using it.

1#ifndef ARRAY2D_H
2#define ARRAY2D_H
3 
4#include <vector>
5 
6template<class dataType>
7 
8class Array2D
9{
10 size_t mCol;
11 std::vector<dataType> mData;
12 
13 public:
14 
15 Array2D(size_t rows, size_t cols) : mData(rows*cols), mCol(cols) { }
16 
17 dataType& operator()(size_t row, size_t col)
18 {
19 return mData[row*mCol + col];
20 }
21 
22 const dataType& operator()(size_t row, size_t col) const
23 {
24 return mData[row*mCol + col];
25 }
26};
27 
28#endif

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

You could change your class into 3D instead of 2D , just add a variable for layer or depth or height and resize everything. You would have to rewrite your operators() then but that wouldn't be too hard.

After that , just load one layer from one text map at a time.

valentino
Member #8,853
July 2007

Quote:

After that , just load one layer from one text map at a time.

Could you give me an example of how that would be done or how that would look in the txt?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

bool LoadMapLevel(const string& filename , int maplevel) {
  // maplevel from 0 to number of levels - 1 , with 0 being ground level or lowest
  ifstream file;
  file.open(("data/"+filename+".txt").c_str() , ios::in);
  if (!(file.good())) {return false;}
  for (int Row = 0 ; Row < MAP_H ; Row++) {
    for (int Col = 0 ; Col < MAP_W ; Col++) {
      file >> mMapArray[( (maplevel*(MaxNumRow*MaxNumCol) + Row*MaxNumCol + Col)];
      if (file.eof()) {return false;}
    }
  }
  return true;
}

I would make LoadMapLevel a member of a wrapper class for Array3D and I would make Array3D know all of its bounds , not just the number of columns.

Store each layer of the map in a different text file.

valentino
Member #8,853
July 2007

Quote:

Store each layer of the map in a different text file.

Is there any way I can avoid that? I want to try and keep the layers for the same map in same txt.

Audric
Member #907
January 2001

Put the layers one after each other, and put the loading inside a for(l = 0; l < LAYERS_NUMBER; l++) { /* loading here */ } ?

Jonatan Hedborg
Member #4,886
July 2004
avatar

Quote:

Oh.. I always thought it goes x then y. Thanks!

Think about it and it should make sense. Just follow the loop in your head.

Go to: