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.

How do I load Levels in my game, as in Layer 1 would be Objects, Layer 2 would be Characters and so on. I only need 3 layers, and they will all be put on top of each other. i.e having a flower with a transparent background to be put on grass or dirt on the layer below.I would like to Read From the same file too. How would i go about doing this? Any help would be appreciated.

I load the map from a level file which are just numbers corresponding to a tile in the tilesheet.

Here is the level file

[Layer1]
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
[Layer2]
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
[Layer3]
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

And here is the code that interprets it

void LoadMap(const char *filename, std::vector< std::vector <int> > &map)
{
    std::ifstream openfile(filename); 
    if(openfile.is_open())
    {
        std::string line, value;
        int space;

        while(!openfile.eof())
        {
            std::getline(openfile, line);

            if(line.find("[TileSet]") != std::string::npos)
            {
                state = TileSet;
                continue;
            }
            else if (line.find("[Layer1]") != std::string::npos)
            {
                state = Map;
                continue;
            }

            switch(state)
            {
            case TileSet:
                if(line.length() > 0)
                    tileSet = al_load_bitmap(line.c_str());
                break;
            case Map: 

                std::stringstream str(line);
                std::vector<int> tempVector;

                while(!str.eof())
                {
                    std::getline(str, value, ' ');
                    if(value.length() > 0)
                                 tempVector.push_back(atoi(value.c_str()));
                }
                map.push_back(tempVector);
                break;
            }
        }
    }
    else
    {
  }
  }

and this is how it draws the map. Also the tile sheet is 1280 by 1280 and the tilesizeX and tilesizeY is 64

void DrawMap(std::vector <std::vector <int> > map)
{    
    int mapRowCount = map.size();

    for(int i, j = 0; i < mapRowCount; i ++)
    {
        int mapColCount = map[i].size();

        for (int j = 0; j < mapColCount; ++j)
        {
              int tilesetIndex = map[i][j];
              int tilesetRow = floor(tilesetIndex / TILESET_COLCOUNT);
              int tilesetCol = tilesetIndex % TILESET_COLCOUNT;    
              al_draw_bitmap_region(tileSet, tilesetCol * TileSizeX, tilesetRow * TileSizeY, TileSizeX, TileSizeY, j * TileSizeX, i * TileSizeX, NULL);
        }
    }
}

EDIT: http://i.imgur.com/Ygu0zRE.jpg

share|improve this question
1  
I think it may be overkill to have three entirely separate levels for small details like flowers. You may just want to have the tiles able to store multiple sprites that can have their levels defined individually. –  Byte56 Jan 25 '13 at 23:53
    
I'm not sure exactly what the problem is. Your idea is fine even if it is a bit complicated. Personally I would suggest just using one 'map' layer, and then have a section of your map file dedicated to listing objects and their coordinates (since most likely you will not have an object on every tile). By doing this you would also be able to have several objects on the same tile at once. –  Benjamin Danger Johnson Jan 26 '13 at 0:19
    
@Ben How would i go about doing that? –  Manl400 Jan 26 '13 at 0:22
    
well I would stick with your current file format for the first Layer then add an Objects section. The object section would list something like "<object type> xTileIndex yTileIndex". That should work for general objects. In the case of game actors you could change it to something like "<actor id> currentHp xTileIndex yTileIndex". I apologize if my phrasing is a bit weird, I'm not very good at writing but I will answer any questions you have. –  Benjamin Danger Johnson Jan 26 '13 at 0:37
    
@byte56 Ya but obviously I wont have just a flower but other objects. –  Manl400 Jan 26 '13 at 0:38

3 Answers 3

After dealing with similar project over the last 2 years (as an amateur game developper) I had to face the fact that this method was totally outdated, and somehow more complicated in time than others.

I would advice you reviewing totally the format of your map and the way you handle layers. A good example is the Tile Map Format .TMX(Tmx Map Format documentation here) which can be used with the free and open-sourced Tiled editor(Tiled website).

I find it to be really flexible and convenient. Most of the platformers and RPG games I developp use this file format. Moreover, several code examples exist on the internet for almost every language. I even use it on a professionnal JavaScript project.

I know it doesn't really answers your question but it is a good alternative in my opinion.

share|improve this answer

I didn't watch the code, but if I understood it well, you'd like to use layers on a similar way as they are used in platformers, isn't it?

In that case, I'd suggest you to make an array for every layer and make some cross-effect between them. Here's an example (just parts):

#define x 30
#define y 30

int arr1[x][y];
int arr2[x][y];
int arr3[x][y];

Player player; //makes obecjt "player" belongs to class "Player" 
Wall invisible_wall; //makes obecjt "invisible_wall" belongs to class "Wall" 

player.posX = 10;
player.posY = 20;
player.layer = arr1; //maybe it's wrong, don't deal with it: the matter is that you may do a property that tells the layer the pbject lays on

invisible_wall.X = 10;
invisible_wall.Y = 20; 
invisible_wall.layer = arr1; //maybe it's wrong, don't deal with it: the matter is that you may do a property that tells the layer the pbject lays on

if (player.layer == invisible_wall.layer)
{
stop player; //it's also wrong but you may add here that stops player moving
} else {
let player move; //it's also wrong but you may add here that lets player moving
}

This is not a proper code, but I hope I could get the logic I try to tell.

Also, it may be a wrong idea, but hopefully, it may help.

PS.: Byte56 was right: don't use layers if they are not necessary!

share|improve this answer

A solution to your problem would be that within your map class you create 3 std::vector> each the same size representing each a layer of the map. Then within your loadmap function every time yiu encounter the appropriate layer you push back the integers that represent tiles. Esentially, you have the basis for the system you want, you just need a cotainer for each layer. Then when it comes to rendering, within the nested for loop render the appropriate image for the layers in order from bottom to top. Or you can use a priority map and render in order of priority. If you need it i can always post a simplified snippet of code later.

share|improve this answer

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.