为什么这个整数会无限下降?
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);
我正在尝试使用 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);