SFML community forums

Help => General => Topic started by: mos on September 17, 2016, 08:26:50 pm

Title: Multiple tile layers
Post by: mos on September 17, 2016, 08:26:50 pm
Hello, I followed this tutorial: http://www.sfml-dev.org/tutorials/2.4/graphics-vertex-array.php and was able to draw a simple map. However, I can't figure out how to add a tile on top of another tile.

My tile sheet looks like this:

(http://i.imgur.com/XQMv5SF.png)

As you can see, some have a background while the others have a transparent one. If I draw the transparent background tiles next to one that isn't, it looks out of place:

(http://i.imgur.com/V3PNJxt.png)

So I wanted to draw another tile underneath it; like grass or sand. Do I have to make 2 arrays? I read my array from a XML file:

<?xml version="1.0" encoding="UTF-8"?>

<Level>
        <!-- Location of tile sheet -->
        <Tileset>Resources/Tiles/medieval.png</Tileset>

        <!-- Number of rows and columns on sheet -->
        <SheetRows>7</SheetRows>
        <SheetColumns>18</SheetColumns>
       
        <!-- Size of the world -->
        <WorldWidth>16</WorldWidth>
        <WorldHeight>10</WorldHeight>
       
        <!-- Offsets -->
        <TopOffset>0</TopOffset>
        <BottomOffset>32</BottomOffset>
        <LeftOffset>0</LeftOffset>
        <RightOffset>32</RightOffset>

        <!-- Tiles from sheet -->
        <Map>
                <Row>75  4   75  1   1   1   0   0   1   0   0   0   0   0   0   0</Row>
                <Row>0   4   75  1   0   0   0   0   0   0   44  0   1   57  0   0</Row>
                <Row>0   4   0   75  0   0   0   1   1   0   4   0   0   0   0   0</Row>
                <Row>0   40  24  72  0   0   0   0   0   0   4   0   0   0   0   0</Row>
                <Row>0   0   0   1   0   0   0   0   0   57  4   0   1   0   0   0</Row>
                <Row>0   0   0   0   0   0   0   1   1   0   4   0   0   0   0   0</Row>
                <Row>0   0   0   0   0   0   0   0   0   0   4   0   0   0   0   0</Row>
                <Row>0   0   0   1   0   0   57  0   0   0   4   0   1   0   0   0</Row>
                <Row>0   0   0   1   0   0   57  0   0   0   4   0   1   0   0   0</Row>
                <Row>0   0   0   0   0   0   0   1   1   0   4   0   0   0   0   0</Row>
        </Map>
</Level>
 

Here's my TileMap.cpp code: https://gist.github.com/anonymous/f9ddbf24f684d0552d7fee31f4063155

What's the best way to achieve multiple layers? Any help would be appreciated!
Title: Re: Multiple tile layers
Post by: Mario on September 17, 2016, 09:30:06 pm
That's really up to you. You could also use bitshifting to store two tiles in one number/entry, for example:

    tileentry = tilelayer0 + tilelayer1 * 256;

0 would mean "no tile" here.

So for example, if you just want to draw grass, which could be id 1, you'd end up with:

    tileentry = 1 + 0 * 256 = 1

Note that I'm making up IDs. The actual numbers might be different for you.

If you want to draw grass (1) with a house (20) on top, you'd end up with:

    tileentry = 1 + 20 * 256 = 5121

Of course this makes editing the map more complex, so you might want to create some editor (unless you have one, didn't check your code).

As an alternative, you could introduce a second array/table for the next layer, but by doing this you're essentially wasting space. Imagine a map using only one layer, you'd be increasing the size by 100% without any gains.
Title: Re: Multiple tile layers
Post by: mos on September 18, 2016, 04:23:03 am
I've never done bitshifting before so I'm sure what the tileentry is supposed to be. If I go by the vertex array tutorial linked, would that be tileNumber? If so, not sure what   tileentry = 1 + 20 * 256 = 5121 would mean as the number of tiles don't go that high.

I was going to use the Tiled map editor eventually, but I wanted to know how to do it first on my own. As for your alternative method, I agree. I really don't want to use another array to do this.

Thanks for the reply!
Title: Re: Multiple tile layers
Post by: Tukimitzu on September 18, 2016, 04:55:30 am
Rather than having:

Tile tiles[width][height];

You could have something like:

vector< vector< list<Tile> > > tiles;

Then each position could store an ordered list of the tiles to be drawn at given position. Let's say you separate them with ";" in your xml:

    <Map>
        <Row>75;1  4   75  1   1   1   0   0   1   0   0   0   0   0   0   0</Row>
        <Row>0    1;4   75  1   0   0   0   0   0   0   44  0   1   57  0   0</Row>
        <Row>0    1;4   0   75  0   0   0   1   1   0   4   0   0   0   0   0</Row>
        <Row>0    40   24  1;72  0   0   0   0   0   0   4   0   0   0   0   0</Row>
        <Row>0    0    0   1   0   0   0   0   0   1;57  4   0   1   0   0   0</Row>
        <Row>0    0    0   0   0   0   0   1   1   0   4   0   0   0   0   0</Row>
        <Row>0    0    0   0   0   0   0   0   0   0   4   0   0   0   0   0</Row>
        <Row>0    0    0   1   0   0   57  0   0   0   4   0   1   0   0   0</Row>
        <Row>0    0    0   1   0   0   57  0   0   0   4   0   1   0   0   0</Row>
        <Row>0    0    0   0   0   0   0   1   1   0   4   0   0   0   0   0</Row>
    </Map>

And drawing is easy enough:
for (int i = 0; i < width; i++){
  for (int j = 0; j < height; j++){
    for (auto& tile : tiles[i][j]){
      window.draw(tile);
    }
  }
}
Title: Re: Multiple tile layers
Post by: mos on September 19, 2016, 12:22:47 am
Thank you both. This was really helpful. Going to try and get a working version.