提问者:小点点

在玩蛇游戏中,我如何移动蛇? [已关闭]


我实际上发布了一个类似的问题,但没有任何不工作的代码。 现在我有了一些。 所以我想让snake向一个方向移动(例如:向上),直到我按下另一个按钮(向下,向左,向右),我会改变方向。

然而,我在这段代码中注释掉了其中一个问题,但现在它只以这种方式部分工作:

如果我往上压,我只能再往下压一次,它就会永远移动,如果我往左压或往右压,我只能往上压或往下压,然后交替地往下压或往上压,它就会永远朝那个方向移动

下面是代码:

void Game::ProcessEvents(){
    sf::Event event;
    while (myWindow.pollEvent(event)){
            switch(event.type){
                    case sf::Event::KeyPressed : handlePlayerInput(event.key.code, true); break;
                    //case sf::Event::KeyReleased : handlePlayerInput(event.key.code, false); break;
                    case sf::Event::Closed : myWindow.close(); break;
            }
    }
}

void Game::handlePlayerInput(sf::Keyboard::Key key, bool isPressed){
    if (key == sf::Keyboard::W || key == sf::Keyboard::Up) movingUp = isPressed;
    else if (key == sf::Keyboard::S || key == sf::Keyboard::Down) movingDown = isPressed;
    else if (key == sf::Keyboard::A || key == sf::Keyboard::Left) movingLeft = isPressed;
    else if (key == sf::Keyboard::D || key == sf::Keyboard::Right) movingRight = isPressed;
}

void Game::update(){
    sf::Vector2f movement(0.0f, 0.0f);
    if (movingUp)    {   movingLeft = false; movingRight = false; movingDown = false; movement.y -= 0.1f;}
    if (movingDown)  {   movingUp = false; movingLeft = false; movingRight = false;  movement.y += 0.1f;  }
    if (movingLeft)  {   movingRight = false; movingUp = false; movingDown = false;  movement.x -= 0.1f;  }
    if (movingRight) {   movingLeft = false; movingDown = false; movingUp = false;  movement.x += 0.1f;   }

    isColliding(movement);
}

共2个答案

匿名用户

我并不是最喜欢读取输入,然后将其转换为movation对象的人。 例如,如果MovingUp为true,何时将其设置为false? 答案是永远不会! 那是不可能发生的!

相反,我用一个单个变量创建一个枚举来表示当前的移动方向:

enum Dir { RIGHT, LEFT, UP, DOWN };
Dir curr_dir = RIGHT; // Start the game moving right

现在您的HandlePlayerInput逻辑可能如下所示:

if (key == sf::Keyboard::W || key == sf::Keyboard::Up) curr_dir = UP;
else if (key == sf::Keyboard::S || key == sf::Keyboard::Down) curr_dir = DOWN;
else if (key == sf::Keyboard::A || key == sf::Keyboard::Left) curr_dir = LEFT;
else if (key == sf::Keyboard::D || key == sf::Keyboard::Right) curr_dir = RIGHT;

更新逻辑现在可以是:

switch(curr_dir) {
    case UP:
        movement.y -= 0.1f;
        break;
    case DOWN:
        movement.y += 0.1f;
        break;
    case RIGHT:
        movement.x -= 0.1f;
        break;
    case LEFT:
        movement.x += 0.1f;
        break;
}

匿名用户

我会这样做:

  1. 不是有多个布尔,而是有一个表示方向的变量。 它可以是枚举。
enum class Dir { up, down, left, right };

void Game::handlePlayerInput(sf::Keyboard::Key key, bool isPressed){
    if (key == sf::Keyboard::W || key == sf::Keyboard::Up) direction = Dir::up;
    else if (key == sf::Keyboard::S || key == sf::Keyboard::Down) direction = Dir::down;
    else if (key == sf::Keyboard::A || key == sf::Keyboard::Left) direction = Dir::left;
    else if (key == sf::Keyboard::D || key == sf::Keyboard::Right) direction = Dir::right;

void Game::update(){
    sf::Vector2f movement(0.0f, 0.0f);

    if (direction == Dir::up) movement.y -= 0.1f;
    else if (direction == Dir::down) movement += 0.1f;
    else if (direction == Dir::left) movement.x -= 0.1f;
    else if (direction == Dir::right) movement += 0.1f;

    isColliding(movement);