向量无效下标。 SFML

Vector invalid subscript. SFML

我正在尝试制作贪吃蛇游戏,这个错误可能是其中之一。因此,当我调试和单步执行时,我在 vector 的头文件中得到 link 异常,并且在异常代码中写入 vector 具有无效下标。 (错误原因可以通过 vector bodyPart 调用)。编译器消息:

Unhandled exception at 0x00007FFA227EA799 in snake.exe: Microsoft C++ exception: std::out_of_range at memory location 0x00000052FA7CDFD0.

Snake::Snake(RenderWindow& window)
{
    bodyPart.setPosition(window.getSize().x / 4, window.getSize().y / 4);
    bodyPart.setSize(Vector2f(20.f, 20.f));
    bodyPart.setFillColor(Color(0, 0, 0));
    body.push_back(bodyPart);
}
//Sets default parameters
void Game::restart(RenderWindow& window)
{
    for (int i = 0; i < snake.body.size() - 1; i++)
    {
        snake.body.pop_back();
    }
    snake.bodyPart.setPosition(window.getSize().x / 4, window.getSize().y / 4);
    snake.body.push_back(snake.bodyPart);
}
//Updates game
void Game::tick(RenderWindow& window)
{
    if (snake.body.at(0).getPosition().x == fruit.fruitX && snake.body.at(0).getPosition().y == fruit.fruitY)
    {
        fruit.fruitX = fieldLCorn + rand() % fieldX * fieldY;
        fruit.fruitY = fieldLCorn + rand() % fieldY * fieldX;
        ui.score++;
        snake.body.reserve(1);
        snake.body.push_back(snake.bodyPart);
    }
}
void Game::moveSnake()
{
    switch(dir)
    {
    case 1:
        snake.body.push_back(snake.tail);
        snake.body.at(0).move(0, snake.body.at(0).getPosition().y + 10);
        snake.body.pop_back();
    case 2:
        snake.body.push_back(snake.tail);
        snake.body.at(0).move(0, snake.body.at(0).getPosition().y - 10);
        snake.body.pop_back();
    case 3:
        snake.body.push_back(snake.tail);
        snake.body.at(0).move(snake.body.at(0).getPosition().x + 10, 0);
        snake.body.pop_back();
    case 4:
        snake.body.push_back(snake.tail);
        snake.body.at(0).move(snake.body.at(0).getPosition().x - 10, 0);
        snake.body.pop_back();
    }
}
void Game::countCollision(RenderWindow& window)
{
    //Is snake met border
    if (snake.body.at(0).getPosition().x > 300) restart(window);
    if (snake.body.at(0).getPosition().y > 300) restart(window);
    if (snake.body.at(0).getPosition().x < -300) restart(window);
    if (snake.body.at(0).getPosition().y < -300) restart(window);
    //If snake eats itself
    for (int k = 0; k < snake.body.size() - 1; k++)
    {
        if (snake.body.at(0).getPosition().x == snake.body.at(k).getPosition().y && snake.body.at(0).getPosition().y == snake.body.at(k).getPosition().y)
        {
            restart(window);
        }
    }
}
void Game::render(RenderWindow& window)
{
    for (int i = 0; i < snake.body.size() - 1; i++)
    {
        window.draw(snake.body.at(i));
    }
}

就我在这里看到的情况而言,问题可能出在

snake.body.at(0)

您在代码中多次使用,当时 body 可能没有元素,因此没有 0 的元素

在你的 Game::render() 函数中,循环的条件显然会给出一个 'out-of-bound' 错误,因为在 for (int i = 0; i < snake.body.size() - 1; i++) 中它会尝试访问最后一个元素的 1-past。因此,您应该检查 <= 或删除 -1(建议)。

所以我通过在主体容器中添加头部部分并使用不带参数的构造函数解决了问题,我还删除了不需要的矢量大小检查(否)。这是我的新代码:

Snake::Snake()
{
    body.reserve(4);
    head.setPosition(400, 400);
    head.setSize(Vector2f(20.f, 20.f));
    head.setFillColor(Color(0, 0, 0));
    body.push_back(head);
    for (int i = 0; i < 3; i++)
    {
        bodyPart.setPosition(body.at(i).getPosition().x - 20, body.at(i).getPosition().y - 20);
        bodyPart.setSize(Vector2f(20.f, 20.f));
        bodyPart.setFillColor(Color(0, 0, 0));
        body.push_back(bodyPart);
    }
}
void Game::restart()
{
    for (unsigned int i = 0; i < snake.body.size(); i--)
    {
        snake.body.pop_back();
    }
    snake.head.setPosition(400, 400);
}
void Game::tick()
{
    moveSnake();
    if (snake.body.at(0).getPosition().x == fruit.fruitX && snake.body.at(0).getPosition().y == fruit.fruitY)
    {
        snake.body.reserve(1);
        for (unsigned int i = snake.body.size() - 1;i > 0;i--)
        {
            snake.body.at(i).setPosition(snake.body.at(i - 1).getPosition().x - 20, snake.body.at(i - 1).getPosition().y - 20);
        }
    }
    countCollision();
}
void Game::moveSnake()
{
    switch(dir)
    {
    case 1:
        snake.body.push_back(snake.bodyPart);
        snake.body.at(0).move(0, snake.body.at(0).getPosition().y + 10);
        snake.body.pop_back();
    case 2:
        snake.body.push_back(snake.bodyPart);
        snake.body.at(0).move(0, snake.body.at(0).getPosition().y - 10);
        snake.body.pop_back();
    case 3:
        snake.body.push_back(snake.bodyPart);
        snake.body.at(0).move(snake.body.at(0).getPosition().x + 10, 0);
        snake.body.pop_back();
    case 4:
        snake.body.push_back(snake.bodyPart);
        snake.body.at(0).move(snake.body.at(0).getPosition().x - 10, 0);
        snake.body.pop_back();
    }
}
void Game::countCollision()
{
    if (snake.body.size() >= 5)
    {
        //If snake eats itself
        for (unsigned int k = 1; k < snake.body.size(); k++)
        {
            if (snake.body.at(0).getPosition().x == snake.body.at(k).getPosition().y && snake.body.at(0).getPosition().y == snake.body.at(k).getPosition().y)
            {
                restart();
            }
        }
    }
}
void Game::render(RenderWindow& window)
{
    for (int i = 0; i < snake.body.size(); i++)
    {
        window.draw(snake.body.at(i));
    }
}