简体   繁体   中英

sf::Vector2i as key in std::map shows as (1, 1) if the Y value is 1 even if the X value is 0

I'm trying to use sf::Vector2i as the key for a tile map in my program. As I wrote in the title, no matter what the X value is, it'll instead show only the Y value for both X and Y in the map.

Here's an image from the debugger that shows what I mean:

调试器映像

As you can see, the key value goes like this: [0][0], [1][1], [2][2], [3][3], etc while the actual value is what I'd expect (0,0 - 0,1 - 0,2 - 0,3 etc).

The declaration for the map:

std::map<sf::Vector2i, std::pair<sf::Vector2f, std::list<unsigned int>>, VectorComparator> tileMap;

The key (sf::Vector2i) is the tile position, the sf::Vector2f in the value pair is the actual position (so tileMap[0,1].first would be 0,32 as the tiles are spaced apart by 32)

Here's the loop's that populates the map:

int xPos {0}, yPos {0};
for (int i {0}; i < width / WorldInfo::tileSize; ++i)
{
    for (int z {0}; z < height / WorldInfo::tileSize; ++z)
    {
        tileMap[sf::Vector2i(i, z)].first = sf::Vector2f(xPos, yPos);
        tileMap[sf::Vector2i(i, z)].second = std::list<unsigned int>();

        yPos += WorldInfo::tileSize;
    }

    yPos = 0;
    xPos += WorldInfo::tileSize;
}

The map comparator:

struct VectorComparator
{
    bool operator() (sf::Vector2i lhs, sf::Vector2i rhs) const
    {
        return lhs.x + lhs.y < rhs.x + rhs.y;
    }
};

Any idea what's going on here? It makes no sense to me why the value is correct while the key doesn't reflect that.

Edit:

If I manually add a tile like so:

tileMap[sf::Vector2i(0, 5)].first = sf::Vector2f(50, 50);

The key for that entry will also be [0][0] if it was added first. If I add it after another, it'll be [1][1] and so on. Seems like the key value doesn't care about the contents of sf::Vector2i?

Your comparision operator is wrong.

You compare manhattan distance of two points, which is wrong. 0,1 point and 1,0 point has the same distance (0 + 1 == 1 + 0), thus only one will exist in tileMap (later one).

Try this:

struct VectorComparator
{
    bool operator() (sf::Vector2i lhs, sf::Vector2i rhs) const
    {
        return lhs.x < rhs.x || (lhs.x == rhs.x && lhs.y < rhs.y);
    }
};

EDIT: as a minor sugestion i'd use std::vector instead of std::list (faster in almost all cases, unless you really need to have pointers to elements valid at all times). I would also use std::unordered_map instead of std::map (once again, faster).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM