如何在 SFML 中检查二维地图上的碰撞?

How to check collision on 2D map in SFML?

我有一个 RectangleShape 墙,我为我的 2D 地图上的每个“1”绘制了一个对象:

int map[5][8] =
{
    { 1, 1, 1, 1, 1, 1, 1, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 0, 1, 0, 1, 1, 0, 1 },
    { 1, 2, 1, 0, 0, 0, 3, 1 },
    { 1, 1, 1, 1, 1, 1, 1, 1 }
};

sf::RectangleShape player;
    player.setSize(sf::Vector2f(32,32));

    sf::RectangleShape wall;
    wall.setSize(sf::Vector2f(32,32));
    wall.setFillColor(sf::Color(40, 199, 40));

for (int mapX= 0; mapX< 8; mapX++)
        {
            for (int mapY= 0; mapY< 5; mapY++)
            {
                if (map[mapY][mapX] == 1)
                {
                    wall.setPosition(mapX * 32, mapY * 32);
                    window.draw(wall);
                }
}
}

我检查是否与下面列出的代码发生碰撞,但这仅适用于最后绘制的墙。如何解决这个问题?只有一个对象墙,我想为我的 2D 阵列贴图检查所有绘制的墙的碰撞。

if (event.type == sf::Event::TextEntered)
            {
                fPlayerY_t = fPlayerY;
                fPlayerX_t = fPlayerX;

                if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) fPlayerY_t = fPlayerY - 32;
                else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) fPlayerY_t = fPlayerY + 32;
                else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) fPlayerX_t = fPlayerX + 32;
                else if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) fPlayerX_t = fPlayerX - 32;

                // temp pos
                player.setPosition(fPlayerX_t, fPlayerY_t);

                // collision with wall
                if (player.getPosition().x == wall.getPosition().x &&
                    player.getPosition().y == wall.getPosition().y)
                {
                    // back to prev position
                    player.setPosition(fPlayerX, fPlayerY);
                }
                else
                {
                    // No collision
                    fPlayerX = fPlayerX_t;
                    fPlayerY = fPlayerY_t;
                }
}

将玩家的坐标转换为数组坐标,然后检查是否map[x][y] == 1。 所以不必在每个游戏循环中遍历整个地图。 转换成数组坐标,使用int转换:

int playerTileX = (int)(playerWorldX / 32);
int playerTileY = (int)(playerWorldY / 32);

if(map[playerTileX ][playerTileY ] == 1)
{
    // collision.
}
else
{
    // no collision.
}

我不喜欢这个解决方案的地方:它只检查瓷砖碰撞,你必须确保每面墙的尺寸都相同(这里是 32*32)。