当你吃苹果时我的贪吃蛇游戏崩溃,苹果在选择新位置后在你体内生成(C++,SDL)

My game of Snake crashes when you eat an apple, and the apple spawns inside your body after picking a new position (C++, SDL)

我想我会尝试制作 贪吃蛇,因为它是一款非常容易制作的游戏。我遇到了苹果会在蛇体内产卵的问题,所以我想出了一个方法来防止这种情况发生:

void getRandomApplePos() {
    // variable that tells the while loop whether the moving of the apple was successful
    bool success;

    // variable that is set to false if the apple is inside the snakes body
    bool appleNotInside;

    // Tells the collision to stop testing for collision until the apple has successfully moved
    bool appleHasMoved;

    // sets the variables 
    success = false;
    appleNotInside = false;
    appleHasMoved = false;

    // while the apple spawns inside the snake, it keeps generating new positions 
    while (!success) {
        // random seed
        srand((unsigned int)time(NULL));

        // gets a random position
        int randomX = rand() % 769;
        int randomY = rand() % 673;

        // resets the two variables if this while loop as ran again
        apple.delta_pos_x = 0;
        apple.delta_pos_y = 0;
    
    // checks to see if the apple has spawned in the same exact position
        while (apple.delta_pos_x == 0 && apple.delta_pos_y == 0) {
            // gets the previous poition of the apple
            apple.prevPos_x = apple.x;
            apple.prevPos_y = apple.y;

            // picks a new apple position
            apple.x = round((randomX) / 32) * 32;
            apple.y = round((randomY) / 32) * 32;

            // gets the new apple position
            apple.currentPos_x = apple.x;
            apple.currentPos_y = apple.y;

            // sets the difference between the positions, if it's 0, then it has spawned in the same exact location
            apple.delta_pos_x = (float)(apple.currentPos_x - apple.prevPos_x);
            apple.delta_pos_y = (float)(apple.currentPos_y - apple.prevPos_y);
        }

        // checks to see if the snake length is only one, as to make the list not go out of index
        if (snake.bodyLength == 1) {
            // if the apple happens to spawn inside the snake with a length of 1, it will add false to the appleInSnake vector, else it adds true
            if (apple.x == snakeBody[0][0] && apple.y == snakeBody[0][1]) {
                appleNotInside = false;
                appleInSnake.push_back(appleNotInside);
            }
            else {
                appleNotInside = true;
                appleInSnake.push_back(appleNotInside);
            }
        }
        else {
            // if the apple happens to spawn inside the currently compared snakeBodyPosition, it will add false to the appleInSnake vector, else it adds true
            for (int i = 0; i < snakeBody.size(); i++) {
                if (apple.x == snakeBody[i][0] && apple.y == snakeBody[i][1]){
                    appleNotInside = false;
                    appleInSnake.push_back(appleNotInside);
                }
                else {
                    appleNotInside = true;
                    appleInSnake.push_back(appleNotInside);
                }
            }
        }

        // if false appears inside the appleInSnake vector at all, it sets success to false and goes through the loop again. Else it breaks out.
        if (std::find(appleInSnake.begin(), appleInSnake.end(), false) != appleInSnake.end()) {
            success = false;
        }
        else {
            success = true;
        }

        //clears appleInSnake so that it can take in a new comparision
        appleInSnake.clear();
    }

    // tells the collision to start back up again
    appleHasMoved = true;

}

所以,每当苹果最终在蛇体内产卵时,它就会直接崩溃。我怀疑某种无限循环,但我无法解释为什么会发生这种情况。

您正在循环中初始化随机数生成器。 请注意,RNG 是 确定性的 。这意味着您最终将再次绘制与上一个循环相同的数字。

在程序开始时初始化一次 RNG。这样,每次循环中绘制的数字可能会有所不同。

您可能想知道,粗暴地使用 time() 应该可以防止这种情况发生。 time() 的典型实现将具有秒的粒度。因此,您只希望 return 值每秒更改一次,因此,您会在循环中一遍又一遍地进行相同的初始化。