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).