为什么这个整数会无限下降?

Why is this integer descelating infinitely?

我正在尝试使用 SFML 和 C++ 制作一个简单的刽子手游戏,但我 运行 遇到了一个问题,每次都没有输入正确的字母,而是输入了一个字母。似乎每次都会发生一个恒定的循环,将 bodyParts 减少到 0,然后再减少到负无穷大。游戏开始没有键盘输入,为什么会无限往下迭代?谢谢!

#include <SFML/Graphics.hpp>
#include <iostream>
#include <string>

using namespace sf;
using namespace std;

int main()
{
    static String WORD = "word";
    char letter1 = '_';
    char letter2 = '_';
    char letter3 = '_';
    char letter4 = '_';
    int bodyParts = 6;
    int xoffset = 150;
    int yoffset = 50;
    bool playing = true;
    bool inputLetter = false;
    RenderWindow window(VideoMode(400, 400), "Hangman - through the might of SFML");
    // Word Bank
    sf::Font font;
    if (!font.loadFromFile("/home/brandon/Dropbox/Brandon-Nick/C++/Qt-Creator/SFML/Hangman/Hangman/arial.ttf"))
    {
        // error...
    }
    Text letterbankText;
    letterbankText.setFont(font);
    letterbankText.setString("---LETTER BANK---");
    letterbankText.setCharacterSize(14);
    letterbankText.setColor(Color::White);
    letterbankText.setPosition(0, 50);
    Text letterbank;
    letterbank.setFont(font);
    letterbank.setString(" \t _ _ _ _ ");
    letterbank.setCharacterSize(14);
    letterbank.setColor(Color::White);
    letterbank.setPosition(0, 75);
    // Hangman character
    CircleShape head(50.f);
    head.setFillColor(Color::Green);
    head.setPosition(xoffset, yoffset + 0);
    RectangleShape body(Vector2f(10, 90));
    body.setPosition(xoffset + 45, yoffset + 100);
    body.setFillColor(Color::Blue);
    RectangleShape rightArm(Vector2f(60, 10));
    rightArm.setPosition(xoffset + 55, yoffset + 120);
    rightArm.setFillColor(Color::Magenta);
    RectangleShape leftArm(Vector2f(60, 10));
    leftArm.setPosition(xoffset - 15, yoffset + 120);
    leftArm.setFillColor(Color::Yellow);
    RectangleShape leftLeg(Vector2f(60, 10));
    leftLeg.setPosition(xoffset - 15 + 65, yoffset + 190);
    leftLeg.setFillColor(Color::White);
    leftLeg.rotate(135);
    RectangleShape rightLeg(Vector2f(60, 10));
    rightLeg.setPosition(xoffset - 15 + 75, yoffset + 182.5);
    rightLeg.setFillColor(Color::Cyan);
    rightLeg.rotate(45);
    while (window.isOpen())
    {
        Event event;
        while (window.pollEvent(event))
        {
            if (event.type == Event::Closed)
                window.close();
        }
        while(playing){
            inputLetter = false;
            window.clear();
            while(inputLetter == false){
                // Input letter guess
                if (Keyboard::isKeyPressed(Keyboard::W))
                {
                    letter1 = 'W';
                    letterbank.setString(" \t" + String(letter1) + " " + letter2 + " " + letter3 + " " + letter4);
                    inputLetter = true;
                }
                else if (Keyboard::isKeyPressed(Keyboard::O))
                {
                    letter2 = 'o';
                    letterbank.setString(" \t" + String(letter1) + " " + letter2 + " " + letter3 + " " + letter4);
                    inputLetter = true;
                }
                else if (Keyboard::isKeyPressed(Keyboard::R))
                {
                    letter3 = 'r';
                    letterbank.setString(" \t" + String(letter1) + " " + letter2 + " " + letter3 + " " + letter4);
                    inputLetter = true;
                }
                else if (Keyboard::isKeyPressed(Keyboard::D))
                {
                    letter4 = 'd';
                    letterbank.setString(" \t" + String(letter1) + " " + letter2 + " " + letter3 + " " + letter4);
                    inputLetter = true;
                }
                else if(Event::KeyPressed){
                    bodyParts -= 1;
                    inputLetter = true;
                }
                else
                    inputLetter = false;
            }
            switch(bodyParts){
                case 6:
                    window.draw(head);
                case 5:
                    window.draw(body);
                case 4:
                    window.draw(leftArm);
                case 3:
                    window.draw(rightArm);
                case 2:
                    window.draw(leftLeg);
                case 1:
                    window.draw(rightLeg);
                    break;
                default:
                    cout << bodyParts;
            }
            window.draw(letterbankText);
            window.draw(letterbank);
            window.display();
        }
    }
    return 0;
}

'playing' 一开始设置为 true 。也许需要在某处将其设置为 false 才能跳出内循环。或者可能需要一些其他的循环退出条件语句。

我成功了。我必须将我的键盘监听器放在 pollevent 事件中。这是更新后的代码:

#include <SFML/Graphics.hpp>
#include <iostream>
#include <string>

using namespace sf;
using namespace std;


int main()
{
static String WORD = "word";

char letter1 = '_';
char letter2 = '_';
char letter3 = '_';
char letter4 = '_';

int bodyParts = 6;


int xoffset = 150;
int yoffset = 50;

bool playing = true;
bool inputLetter = false;


RenderWindow window(VideoMode(400, 400), "Hangman - through the might of SFML");

// Word Bank
sf::Font font;
if (!font.loadFromFile("/home/brandon/Dropbox/Brandon-Nick/C++/Qt-Creator/SFML/Hangman/Hangman/arial.ttf"))
{
    // error...
}

Text letterbankText;
letterbankText.setFont(font);
letterbankText.setString("---LETTER BANK---");
letterbankText.setCharacterSize(14);
letterbankText.setColor(Color::White);
letterbankText.setPosition(0, 50);

Text letterbank;
letterbank.setFont(font);
letterbank.setString(" \t _ _ _ _ ");
letterbank.setCharacterSize(14);
letterbank.setColor(Color::White);
letterbank.setPosition(0, 75);


// Hangman character
CircleShape head(50.f);
head.setFillColor(Color::Green);
head.setPosition(xoffset, yoffset + 0);

RectangleShape body(Vector2f(10, 90));
body.setPosition(xoffset + 45, yoffset + 100);
body.setFillColor(Color::Blue);

RectangleShape rightArm(Vector2f(60, 10));
rightArm.setPosition(xoffset + 55, yoffset + 120);
rightArm.setFillColor(Color::Magenta);

RectangleShape leftArm(Vector2f(60, 10));
leftArm.setPosition(xoffset - 15, yoffset + 120);
leftArm.setFillColor(Color::Yellow);

RectangleShape leftLeg(Vector2f(60, 10));
leftLeg.setPosition(xoffset - 15 + 65, yoffset + 190);
leftLeg.setFillColor(Color::White);
leftLeg.rotate(135);

RectangleShape rightLeg(Vector2f(60, 10));
rightLeg.setPosition(xoffset - 15 + 75, yoffset + 182.5);
rightLeg.setFillColor(Color::Cyan);
rightLeg.rotate(45);


while (window.isOpen())
{
    Event event;
    while (window.pollEvent(event))
    {
        if (event.type == Event::Closed)
            window.close();

        if(event.type == Event::KeyPressed){
            if(event.key.code == Keyboard::W){
                letter1 = 'W';
                letterbank.setString(" \t" + String(letter1) + " " + letter2 + " " + letter3 + " " + letter4);
                inputLetter = true;
            }
            else if(event.key.code == Keyboard::O){
                letter2 = 'o';
                letterbank.setString(" \t" + String(letter1) + " " + letter2 + " " + letter3 + " " + letter4);
                inputLetter = true;
            }
            else if(event.key.code == Keyboard::R){
                letter3 = 'r';
                letterbank.setString(" \t" + String(letter1) + " " + letter2 + " " + letter3 + " " + letter4);
                inputLetter = true;
            }
            else if(event.key.code == Keyboard::D){
                letter4 = 'd';
                letterbank.setString(" \t" + String(letter1) + " " + letter2 + " " + letter3 + " " + letter4);
                inputLetter = true;
            }
            else
                bodyParts--;
        }
    }


    inputLetter = false;
    window.clear();



    switch(bodyParts){
    case 6:
        window.draw(head);
    case 5:
        window.draw(body);
    case 4:
        window.draw(leftArm);
    case 3:
        window.draw(rightArm);
    case 2:
        window.draw(leftLeg);
    case 1:
        window.draw(rightLeg);
        break;
    default:
        cout << bodyParts;
    }


    window.draw(letterbankText);
    window.draw(letterbank);
    window.display();



}


return 0;
}

首先我修复了一些问题

else if (sf::Event::KeyPressed){
    bodyParts -= 1;
    inputLetter = true;
}

删除上面的内容,让window.pollEvent()处理事件:

while (window.pollEvent(event))
{
    if (event.type == Event::Closed)
        window.close();
    if (event.type == Event::KeyPressed)
        handleInputs(event.key.code, true);
}

在上面的代码中,我让函数负责玩家输入 handleInputs()

此外,while(playing) 不是必需的,应该删除,因为 while(window.isOpen()) 已经是游戏循环了。

您忘记在 switch 语句中 break,结果在您甚至看不到任何部分之前绘制了所有 body 个部分。我建议创建 bool 类型的变量来决定是否绘制每个 body 部分:

bool drawHead       = false;
bool drawBody       = false;
bool drawRightArm   = false;
bool drawLeftArm    = false;
bool drawRightLeg   = false;
bool drawLeftLeg    = false;

并根据 body 部分打开它们:

switch (bodyParts){
        case 6:
            drawHead = true;
            break;
        case 5:
            drawBody = true;
            break;
        case 4:
            drawLeftArm = true;
            break;
        case 3:
            drawRightArm = true;
            break;
        case 2:
            drawLeftLeg = true;
            break;
        case 1:
            drawRightLeg = true;
            break;
        default:
            ;//cout << bodyParts;
}

终于画出来了:

window.draw(letterbankText);
window.draw(letterbank);
if (drawHead) window.draw(head);
if (drawBody) window.draw(body);
if (drawRightArm) window.draw(rightArm);
if (drawLeftArm) window.draw(leftArm);
if (drawRightLeg) window.draw(rightLeg);
if (drawLeftLeg) window.draw(leftLeg);

Full code here