官术网_书友最值得收藏!

Fixing bugs

Let's discuss the several approaches that might be used in a situation like this. First, the programmer might think about putting a flag somewhere that remembers if the direction has already been set for the current iteration and gets reset afterwards. This would prevent the bug we're experiencing, but would also lock down the number of times a player can interact with the snake. Let's say it moves once a second. That would mean that if you press a key at the beginning of that second, you wouldn't be able to change your mind and hit another key quickly to rectify your wrong decision before the snake moves. That's no good. Let's move on to a new idea.

Another approach may be to keep track of the original direction before any changes were made to that iteration. Then, once the update method gets called, we could check if the original direction, before any changes were made, is the opposite of the newest direction that we've received. If it is, we could simply ignore it and move the snake in the direction before any changes were made. This would fix the bug and not present us with a new one, but it comes with keeping track of one more variable and might get confusing. Imagine that in the future you're presented with a similar bug or a request for a feature that needs you to keep track of another variable on top of this one. Imagine that happens one more time, then another. Very soon, your checking statement might look a little something like this:

if(var1 != something && var2 == something && var3 == true && var4 == !var3 ...)

Now that is what we call a mess. On top of that, imagine you have to check the same variables four times for four different conditions. It quickly becomes apparent that this is a bad design and it shouldn't be used by anyone with intentions of ever showing their code to another person.

You may ask how we can rectify our problem then. Well, we could simply not rely on the use of a variable in the snake class to determine its direction, and instead implement a method that looks at its structure and spits out the direction it's facing, as shown next:

Direction Snake::GetPhysicalDirection(){
    if(m_snakeBody.size() <= 1){
        return Direction::None;
    }

    SnakeSegment& head = m_snakeBody[0];
    SnakeSegment& neck = m_snakeBody[1];

    if(head.position.x == neck.position.x){
        return (head.position.y > neck.position.y ? Direction::Down : Direction::Up);
    } else if(head.position.y == neck.position.y){
        return (head.position.x > neck.position.x ? Direction::Right : Direction::Left);
    }

    return Direction::None;
}

First, we check if the snake is 1 segment long or less; in this case, it doesn't matter which direction it's facing as it wouldn't eat itself if it only had a head, and it wouldn't even have a direction if there are no segments in the vector at all. Assuming it's longer than one segment, we obtain two references: the head and the neck, which is the second piece of the snake right after the head. Then, we simply check the positions of both of them and determine the direction the snake is facing using the same logic as before, while implementing the snake class, as illustrated in the following image:

This will return a proper direction that won't be altered unless the snake moves, so let's adjust our input handling code to cater to these changes:

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up) && m_snake.GetPhysicalDirection() != Direction::Down)
{
    m_snake.SetDirection(Direction::Up);
} else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down) && m_snake.GetPhysicalDirection() != Direction::Up)
{
    m_snake.SetDirection(Direction::Down);
} else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left) && m_snake.GetPhysicalDirection() != Direction::Right)
{
    m_snake.SetDirection(Direction::Left);
} else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right) && m_snake.GetPhysicalDirection() != Direction::Left)
{
    m_snake.SetDirection(Direction::Right);
}

Voila! No more of our snake turning inside out.

There's one more fault with the game that didn't get addressed here on purpose. Try to find it and fix it in order to practise resolving problems like this in the future.

Tip

Hint: It has to do with how many segments the snake has when the game starts.

If you want to do this one fairly, do your best not to reference the code of the finished project that came with this book, as that has it fixed already.

主站蜘蛛池模板: 孟村| 绵阳市| 天镇县| 内黄县| 思茅市| 辽源市| 克东县| 赤壁市| 新竹市| 宁明县| 衡阳市| 沁阳市| 康定县| 苗栗县| 巴彦淖尔市| 安多县| 云南省| 高碑店市| 胶南市| 松阳县| 泾源县| 乐清市| 云南省| 固阳县| 江都市| 阿拉尔市| 开阳县| 连江县| 仙桃市| 鹤壁市| 绍兴市| 湟源县| 绿春县| 太湖县| 谷城县| 博客| 金川县| 定结县| 克什克腾旗| 土默特右旗| 舒城县|