按下键时窗口停止刷新

时间:2015-08-31 03:01:46

标签: c++ window sfml game-loop

每当我按一个键移动精灵时,屏幕都不会更新,直到我释放密钥。我能够解决这个问题的唯一方法就是在每个KeyPressed循环中清除,绘制和显示窗口。

一次完成这些事情更有意义,不受任何按键操作的影响。我不知道为什么这不起作用,或者解决这个问题的最佳方法是什么。

在下面的程序中,我在多个不同的地方发布了清除/绘制/显示代码,希望将它放在正确的位置。到目前为止还没有。冗余无意义。

#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;

}

1 个答案:

答案 0 :(得分:1)

计算机按照预期的顺序运行指令。这段代码:

mywindow.clear(sf::Color::Black);
mywindow.draw(playersprite);
mywindow.draw(enemysprite);
playersprite.setPosition(sf::Vector2f(playerx, playery));
mywindow.display();
sf::sleep(sf::microseconds(5));

更新窗口。如果窗口更新代码没有运行,那么窗口当然不会更新。

如果按下左键,则计算机将运行此循环:

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
}

顺便说一句,你不需要更新事件循环中的窗口 - 除非事件需要很长时间才能处理(他们不应该这样做),那么你将很快完成事件循环。