Window 按下按键时停止刷新
Window stops refreshing when key is pressed
每当我按下一个键来移动精灵时,屏幕不会更新,直到我松开键。我能够解决此问题的唯一方法是在每个 KeyPressed 循环中清除、绘制和显示 window。
独立于任何按键,一次完成这些事情更有意义。我不知道为什么这不起作用,或者解决这个问题的最佳方法是什么。
在下面的程序中,我在多个不同的地方发布了 clear/draw/display 代码,希望将其放在正确的位置会起作用。到目前为止还没有。冗余是没有意义的。
#include <SFML/Window.hpp>
#include <iostream>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
using namespace std;
int main()
{
int windowx = 800;
int windowy = 600;
float playerx = 400.0;
float playery = 300.0;
sf::Sprite playersprite;
sf::Sprite enemysprite;
float playerspeedx = 0;
float playerspeedy = 0;
float playerspeedx2 = 0;
float playerspeedy2 = 0;
float accelerationx = 50.0;
float accelerationy = 50.0;
float deccelerationx = 50.0;
float deccelerationy = 50.0;
float frictionx = 25.0;
float frictiony = 25.0;
float playermaxspeedx = 500.0;
float playermaxspeedy = 200.0;
sf::Texture hoverdrone; //player's sprite
if (!hoverdrone.loadFromFile("hoverdrone.png"))
{
cout << "error loading image";
}
sf::Texture floatdrone; //for sprite enemysprite
if (!floatdrone.loadFromFile("floatdrone.png"))
{
cout << "error loading image";
}
playersprite.setTexture(hoverdrone);
enemysprite.setTexture(floatdrone);
enemysprite.setPosition(sf::Vector2f(400, 400));
playersprite.setPosition(sf::Vector2f(400, 300));
sf::RenderWindow mywindow(sf::VideoMode(windowx, windowy), "FishTank");
//sf::Clock clock; //Begin clock.
//sf::Int32 baseclock = clock.getElapsedTime().asMilliseconds();
// run the program as long as the window is open
while (mywindow.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
sf::Event event;
while (mywindow.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
{
cout <<"You have closed the window."<<endl;
mywindow.close();
}
mywindow.clear(sf::Color::Black);
mywindow.draw(playersprite);
mywindow.draw(enemysprite);
playersprite.setPosition(sf::Vector2f(playerx, playery));
mywindow.display();
sf::sleep(sf::microseconds(5));
// left key is pressed: move our character
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
sf::Clock leftclock;
while (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
playerx -= 0.01; //will replace later with time based movement
sf::Int32 leftclock1 = leftclock.getElapsedTime().asMilliseconds();
cout << leftclock1 << endl;
/*mywindow.clear(sf::Color::Black);
mywindow.draw(playersprite);
mywindow.draw(enemysprite);
playersprite.setPosition(sf::Vector2f(playerx, playery));
mywindow.display();*/
}
}
// right key is pressed: move our character
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
sf::Clock rightclock;
while (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
playerx += 0.01; //will replace later with time based movement
sf::Int32 rightclock1 = rightclock.getElapsedTime().asMilliseconds();
cout << rightclock1 << endl;
/*mywindow.clear(sf::Color::Black);
mywindow.draw(playersprite);
mywindow.draw(enemysprite);
playersprite.setPosition(sf::Vector2f(playerx, playery));
mywindow.display();*/
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
// up key is pressed: move our character
//will replace later with time based movement
(playery--);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
// down key is pressed: move our character
// currently just resets sprite position for testing purposes
playerx = 400.0;
playery = 300.0;
}
if (playerx < 0) //Player cannot leave screen x left boundary
{
playerx = 0;
}
if (playerx > windowx) //Player cannot leave screen x right boundary
{
playerx = windowx - 10;
}
}
mywindow.clear(sf::Color::Black);
mywindow.draw(playersprite);
mywindow.draw(enemysprite);
playersprite.setPosition(sf::Vector2f(playerx, playery));
mywindow.display();
sf::sleep(sf::microseconds(5));
}
mywindow.clear(sf::Color::Black);
mywindow.draw(playersprite);
mywindow.draw(enemysprite);
playersprite.setPosition(sf::Vector2f(playerx, playery));
mywindow.display();
sf::sleep(sf::microseconds(5));
return 0;
}
计算机运行按照它应该的顺序执行指令。此代码:
mywindow.clear(sf::Color::Black);
mywindow.draw(playersprite);
mywindow.draw(enemysprite);
playersprite.setPosition(sf::Vector2f(playerx, playery));
mywindow.display();
sf::sleep(sf::microseconds(5));
更新 window。如果 window 更新代码没有 运行,那么 window 当然不会更新。
如果按下左键,那么电脑会运行这样循环:
while (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
playerx -= 0.01; //will replace later with time based movement
sf::Int32 leftclock1 = leftclock.getElapsedTime().asMilliseconds();
cout << leftclock1 << endl;
// there was commented-out code here; I removed it to save space in this answer
}
它将检查左键是否仍被按下。如果是,它会将玩家向左移动一点,打印时间,然后重复。所以它会再次检查左键是否仍然被按下。如果是,它将再次向左移动玩家一点,再次打印时间,然后再次重复。等等。在玩家松开左键之前,此循环永远不会完成 - 它只会坐在那里将玩家向左移动(不是你可以看到它)并随着时间向你的控制台发送垃圾邮件。
对此的典型解决方案是删除那些检查按键的循环。保留 if
,但将它们移到 外部 事件处理循环。所以你有这样的东西:(不是实际代码)
while(window is open)
{
while(have an event to process)
{
process event
}
if(left key pressed)
{
move player left
}
if(right key pressed)
{
move player right
}
// and so on
update window
}
顺便说一下,您不需要更新事件循环内的 window - 除非事件需要很长时间来处理(他们不应该这样做)然后您将完成事件循环很快。
每当我按下一个键来移动精灵时,屏幕不会更新,直到我松开键。我能够解决此问题的唯一方法是在每个 KeyPressed 循环中清除、绘制和显示 window。
独立于任何按键,一次完成这些事情更有意义。我不知道为什么这不起作用,或者解决这个问题的最佳方法是什么。
在下面的程序中,我在多个不同的地方发布了 clear/draw/display 代码,希望将其放在正确的位置会起作用。到目前为止还没有。冗余是没有意义的。
#include <SFML/Window.hpp>
#include <iostream>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
using namespace std;
int main()
{
int windowx = 800;
int windowy = 600;
float playerx = 400.0;
float playery = 300.0;
sf::Sprite playersprite;
sf::Sprite enemysprite;
float playerspeedx = 0;
float playerspeedy = 0;
float playerspeedx2 = 0;
float playerspeedy2 = 0;
float accelerationx = 50.0;
float accelerationy = 50.0;
float deccelerationx = 50.0;
float deccelerationy = 50.0;
float frictionx = 25.0;
float frictiony = 25.0;
float playermaxspeedx = 500.0;
float playermaxspeedy = 200.0;
sf::Texture hoverdrone; //player's sprite
if (!hoverdrone.loadFromFile("hoverdrone.png"))
{
cout << "error loading image";
}
sf::Texture floatdrone; //for sprite enemysprite
if (!floatdrone.loadFromFile("floatdrone.png"))
{
cout << "error loading image";
}
playersprite.setTexture(hoverdrone);
enemysprite.setTexture(floatdrone);
enemysprite.setPosition(sf::Vector2f(400, 400));
playersprite.setPosition(sf::Vector2f(400, 300));
sf::RenderWindow mywindow(sf::VideoMode(windowx, windowy), "FishTank");
//sf::Clock clock; //Begin clock.
//sf::Int32 baseclock = clock.getElapsedTime().asMilliseconds();
// run the program as long as the window is open
while (mywindow.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
sf::Event event;
while (mywindow.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
{
cout <<"You have closed the window."<<endl;
mywindow.close();
}
mywindow.clear(sf::Color::Black);
mywindow.draw(playersprite);
mywindow.draw(enemysprite);
playersprite.setPosition(sf::Vector2f(playerx, playery));
mywindow.display();
sf::sleep(sf::microseconds(5));
// left key is pressed: move our character
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
sf::Clock leftclock;
while (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
playerx -= 0.01; //will replace later with time based movement
sf::Int32 leftclock1 = leftclock.getElapsedTime().asMilliseconds();
cout << leftclock1 << endl;
/*mywindow.clear(sf::Color::Black);
mywindow.draw(playersprite);
mywindow.draw(enemysprite);
playersprite.setPosition(sf::Vector2f(playerx, playery));
mywindow.display();*/
}
}
// right key is pressed: move our character
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
sf::Clock rightclock;
while (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
playerx += 0.01; //will replace later with time based movement
sf::Int32 rightclock1 = rightclock.getElapsedTime().asMilliseconds();
cout << rightclock1 << endl;
/*mywindow.clear(sf::Color::Black);
mywindow.draw(playersprite);
mywindow.draw(enemysprite);
playersprite.setPosition(sf::Vector2f(playerx, playery));
mywindow.display();*/
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
// up key is pressed: move our character
//will replace later with time based movement
(playery--);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
// down key is pressed: move our character
// currently just resets sprite position for testing purposes
playerx = 400.0;
playery = 300.0;
}
if (playerx < 0) //Player cannot leave screen x left boundary
{
playerx = 0;
}
if (playerx > windowx) //Player cannot leave screen x right boundary
{
playerx = windowx - 10;
}
}
mywindow.clear(sf::Color::Black);
mywindow.draw(playersprite);
mywindow.draw(enemysprite);
playersprite.setPosition(sf::Vector2f(playerx, playery));
mywindow.display();
sf::sleep(sf::microseconds(5));
}
mywindow.clear(sf::Color::Black);
mywindow.draw(playersprite);
mywindow.draw(enemysprite);
playersprite.setPosition(sf::Vector2f(playerx, playery));
mywindow.display();
sf::sleep(sf::microseconds(5));
return 0;
}
计算机运行按照它应该的顺序执行指令。此代码:
mywindow.clear(sf::Color::Black);
mywindow.draw(playersprite);
mywindow.draw(enemysprite);
playersprite.setPosition(sf::Vector2f(playerx, playery));
mywindow.display();
sf::sleep(sf::microseconds(5));
更新 window。如果 window 更新代码没有 运行,那么 window 当然不会更新。
如果按下左键,那么电脑会运行这样循环:
while (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
playerx -= 0.01; //will replace later with time based movement
sf::Int32 leftclock1 = leftclock.getElapsedTime().asMilliseconds();
cout << leftclock1 << endl;
// there was commented-out code here; I removed it to save space in this answer
}
它将检查左键是否仍被按下。如果是,它会将玩家向左移动一点,打印时间,然后重复。所以它会再次检查左键是否仍然被按下。如果是,它将再次向左移动玩家一点,再次打印时间,然后再次重复。等等。在玩家松开左键之前,此循环永远不会完成 - 它只会坐在那里将玩家向左移动(不是你可以看到它)并随着时间向你的控制台发送垃圾邮件。
对此的典型解决方案是删除那些检查按键的循环。保留 if
,但将它们移到 外部 事件处理循环。所以你有这样的东西:(不是实际代码)
while(window is open)
{
while(have an event to process)
{
process event
}
if(left key pressed)
{
move player left
}
if(right key pressed)
{
move player right
}
// and so on
update window
}
顺便说一下,您不需要更新事件循环内的 window - 除非事件需要很长时间来处理(他们不应该这样做)然后您将完成事件循环很快。