sf :: Vector2i в качестве ключа в std :: map отображается как (1, 1), если значение Y равно 1, даже если значение X равно 0 - PullRequest
1 голос
/ 08 июня 2019

Я пытаюсь использовать sf :: Vector2i в качестве ключа для карты тайлов в моей программе.Как я писал в заголовке, независимо от значения X вместо него будет отображаться только значение Y для X и Y на карте.

Вот изображение отладчика, которое показывает, что я имею в виду:

debugger image

Как видите, значение ключа выглядит следующим образом: [0] [0], [1] [1], [2] [2], [3] [3] и т. Д., А фактическое значение соответствует ожидаемому (0,0 - 0,1 - 0,2 - 0,3 и т. Д.).

Объявление для карты:

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

Ключ (sf :: Vector2i) - это позиция тайла, sf :: Vector2f в паре значений - это фактическая позиция (поэтому tileMap [0,1] .first будет 0,32 какплитки разделены на 32)

Вот цикл, который заполняет карту:

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;
}

Компаратор карты:

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

Есть идеи, что здесь происходит?Мне не имеет смысла, почему значение является правильным, в то время как ключ не отражает это.

Редактировать:

Если я вручную добавлю плитку следующим образом:

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

Ключ для этой записи также будет [0] [0], если он был добавлен первым.Если я добавлю это за другим, это будет [1] [1] и так далее.Похоже, значение ключа не заботится о содержимом sf :: Vector2i?

1 Ответ

2 голосов
/ 08 июня 2019

Ваш оператор сравнения неверен.

Вы сравниваете манхэттенское расстояние двух точек, что неправильно. Точки 0,1 и 1,0 имеют одинаковое расстояние (0 + 1 == 1 + 0), поэтому в tileMap будет существовать только одна точка (позднее).

Попробуйте это:

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: в качестве незначительного предложения я бы использовал std :: vector вместо std :: list (быстрее почти во всех случаях, если только вам действительно не нужны указатели на элементы, действительные всегда). Я бы также использовал std :: unordered_map вместо std :: map (еще раз, быстрее).

...