SFML游戏C ++中的平铺映射冲突

时间:2018-01-29 23:12:16

标签: c++ sfml

我正在使用SFML库在C ++中创建游戏,并且在实现平铺地图冲突期间(我从txt文件加载地图 - 1代表平台,0' s可用空间)。 https://imgur.com/a/tQZc6

我遇到了同时处理所有四种类型碰撞的问题(从底部,顶部,左侧和右侧)。我的意思是:当没有碰撞时,玩家可以正常移动,但是如果我们碰到了墙,碰撞只出现在FIRST写的if()语句中(在我们的例子中只发生正确的碰撞,其余的被省略)。这是我的代码(我只会粘贴必要的东西)

class Player
{
public:
    Player();
    Player(sf::Texture* texture, sf::Vector2u imageCount, sf::Vector2f position, float switchTime, float speed, float jumpSpeed);
    ~Player();

    void UpdatePlayer(float deltaTime);

    float top, right, left, bottom;

private:
    sf::Vector2f _position;
    float groundHeight = 40; //i've added gravity and hardcoded the ground height to create jumping 
    float _jumpSpeed; // later on, it will be replaced with bottom collision
    const float gravity = 981.0f;
    sf::RectangleShape body;
    float _speed;

};

//Player.cpp
void Player::UpdatePlayer(float deltaTime)
{
    sf::Vector2f movement(0.0f, 0.0f);

    if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
    {
        movement.x -= _speed * deltaTime; //we are using delta time in order to move the object in according to time
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
    {
        movement.x += _speed * deltaTime;
    }

    if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
    {
        movement.y = -sqrt(5.0f * gravity * _jumpSpeed) * deltaTime;
    }
    if (body.getPosition().y + body.getSize().y < groundHeight || movement.y < 0)
    {
        movement.y += gravity * deltaTime;
    }
    else
    {
        body.setPosition(body.getPosition().x, groundHeight - body.getSize().y);
        movement.y = 0;
    }



    bottom = body.getPosition().y + body.getSize().y;
    left = body.getPosition().x;
    right = body.getPosition().x + body.getSize().x;
    top = body.getPosition().y;


    body.move(movement);

}

// Source.cpp

 void LoadCollisionMap(const char*filename)
{
    std::ifstream openfile(filename);
    std::vector<int> tempMap;
    CollMap.clear();

    if (openfile.is_open())
    {
        while (!openfile.eof())
        {
            std::string str, value;
            std::getline(openfile, str);
            std::stringstream stream(str);

            while (std::getline(stream, value, ' '))
            {
                if (value.length() > 0)
                {
                    int a = atoi(value.c_str());
                    tempMap.push_back(a);
                }
            }
            CollMap.push_back(tempMap);
            tempMap.clear();
        }
    }
}
int main()
{
    LoadCollisionMap("Map2.txt"); //Collision map

Player player(&playerTexture, sf::Vector2u(3, 9),sf::Vector2f(100.0f, 150.0f) ,0.3f, 400.0f, 555.0f);

    for (int i = 0; i < CollMap.size(); i++)
    {
        for (int j = 0; j < CollMap[i].size(); j++)
        {
            if (CollMap[i][j] == 1)
            {

                int CollBottom, CollRight, CollLeft, CollTop;
                CollBottom = i * 32 + 32;
                CollTop = i * 32;
                CollLeft = j * 32;
                CollRight = j * 32 + 32;

                if (player.right < CollLeft || player.left > CollRight || player.top > CollBottom || player.bottom < CollTop)
                {
                    //no collision
                }
                else
                {


                    if (player.right > CollLeft)
                    {
                        std::cout << "collision" << std::endl;
                        player.body.setPosition(player.body.getPosition().x - 1, player.body.getPosition().y);
                        break;

                    }


                    if (player.left < CollRight)
                    {
                        std::cout << "collision 2" << std::endl;
                        player.body.setPosition(player.body.getPosition().x + 1, player.body.getPosition().y);
                        break;
                    }


                    if (player.top < CollBottom)
                    {
                        std::cout << "collision 3" << std::endl;

                        player.body.setPosition(player.body.getPosition().x, player.body.getPosition().y + 1);


                        break;


                    }

                    if (player.bottom > CollTop)
                    {
                        std::cout << "collision 4" << std::endl;

                        player.body.setPosition(player.body.getPosition().x, player.body.getPosition().y - 1);
                        break;
                    }


                }

            }

        }
    }

1 个答案:

答案 0 :(得分:0)

运算符break会立即从最嵌套的循环返回。如果要检查所有碰撞,则应从碰撞检查中删除break,并将其替换为例如bool变量。

bool collisionDetected = false;

if (player.right > CollLeft)
{
    std::cout << "collision" << std::endl;
    player.body.setPosition(player.body.getPosition().x - 1, player.body.getPosition().y);

    collisionDetected = true;
}

...

if( collisionDetected ) 
    break;