0
votes

I'm currently using a system the reads the x and y of my tilemap in accordance to the tileset and displays the relative image. This works, however i have found that creating a map by hand is incredibly difficult so decided to use a program called 'Tiled', however this does is read the image, in my case every 32px and set it as a number, let me try to explain, imagine each of the numbers below is a 32x32px square, the number represents how Tiled stores the image as a number until it reaches the width (for the example say the image is 160px or 5 tiles wide) of the image, then on a new lines continue the count..

[1] [2] [3] [4] [5]

[6] [7] [8] [9]

This throws out my script as x and y are not used. Ive tried searching and as many things as i can to adjust my code to read the new format but failed completely, below is my current function to load the map.

void LoadMap(const char*filename)
{
std::ifstream openfile(filename);
std::vector<sf::Vector2i> tempMap;
map.clear();

if(openfile.is_open())
{
    std::string tileLocation;
    openfile >> tileLocation;
    tileTexture.loadFromFile(tileLocation);
    tiles.setTexture(tileTexture);
    while(!openfile.eof())
    {
        std::string str, value;
        std::getline(openfile, str);
        std::stringstream stream(str);

        while(std::getline(stream, value, ' '))
        {
            if(value.length() > 0)
            {
                std::string xx = value.substr(0, value.find(','));
                std::string yy = value.substr(value.find(',') + 1);

                int x, y, i, j;

                for(i = 0; i < xx.length(); i++)
                {
                    if(!isdigit(xx[i]))
                        break;
                }

                for(j = 0; j < yy.length(); j++)
                {
                    if(!isdigit(yy[j]))
                        break;
                }

                x = (i == xx.length()) ? atoi(xx.c_str()) : -1;
                y = (j == yy.length()) ? atoi(yy.c_str()) : -1;

                tempMap.push_back(sf::Vector2i(x, y));
            }
        }

        if(tempMap.size() > 0)
        {
            map.push_back(tempMap);
            tempMap.clear();
        }
    }
}
}

All i need is the script to assign every 32x32 square a number then start a new line and continue until it reaches the end of the tilemap.png

I apologize if this is a silly request, im very new to c++ so any pointers on making my code read the new format would be gratefully appreciated, if you need any other info then let me know.

2

2 Answers

1
votes

If I understand correctly, you have this correspondence and you want to convert N to {x, y} and/or vice versa.

X = 1    2    3    4    5
  [ 1] [ 2] [ 3] [ 4] [ 5] y = 0
  [ 6] [ 7] [ 8] [ 9] [10] y = 1
  [ N]

So, following may help

void NToXY(unsigned int N, unsigned int& x, unsigned int& y)
{
    x = (N - 1) % 5 + 1;
    y = (N - 1) / 5 + 1;
}

void XYToN(unsigned int x, unsigned int y, unsigned int& N)
{
    N = (y - 1) * 5 + x;
}
0
votes

Here's an article that covers the logic behind how tiled understands map data. Parsing and Rendering Tiled TMX Format Maps in Your Own Game Engine

It discusses how to convert (x,y) coordinates into the 'gid' that Tiled uses.

The gist of it is that they are using a 1d Array to store all the tile data for the in-game map (and also, the use a 1d array to index into the tile's texture map). The idea here is that in a compact 1d array of numbers, you may be able to leverage a performance increase due to cache loading.

Here is another question on here that covers this technique in more detail: Map a 2D array onto a 1D array C

It would seem that Jarod42's answer has the functions you'd need to do the math/conversion. This would be useful to convert your systems over temporarily. I'd recommend rewriting your engine to leverage the GID property more directly though since it will save you some pain. You can keep the conversion functions around as helper functions for later.