c++ - Window stops refreshing when key is pressed -
whenever press key move sprite, screen not update until release key. way i've been able fix clear, draw, , display window within each , every keypressed loop.
it makes more sense each of these things 1 time, independent of key-presses. don't know why isn't working, or best way of fixing be.
in program below, posted clear/draw/display code in multiple different places hoping putting in right place work. far hasn't. redundancy otherwise pointless.
#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 program long window open while (mywindow.isopen()) { // check window's events triggered since last iteration of loop sf::event event; while (mywindow.pollevent(event)) { // "close requested" event: close window if (event.type == sf::event::closed) { cout <<"you have closed 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 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 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 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 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)) { // key pressed: move our character //will replace later time based movement (playery--); } if (sf::keyboard::iskeypressed(sf::keyboard::down)) { // down key pressed: move our character // resets sprite position 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;
}
the computer runs instructions in order it's supposed to. code:
mywindow.clear(sf::color::black); mywindow.draw(playersprite); mywindow.draw(enemysprite); playersprite.setposition(sf::vector2f(playerx, playery)); mywindow.display(); sf::sleep(sf::microseconds(5));
updates window. if window-updating code doesn't run, of course window doesn't updated.
if left key pressed, computer run loop:
while (sf::keyboard::iskeypressed(sf::keyboard::left)) { playerx -= 0.01; //will replace later time based movement sf::int32 leftclock1 = leftclock.getelapsedtime().asmilliseconds(); cout << leftclock1 << endl; // there commented-out code here; removed save space in answer }
it check if left key still pressed. if is, move player left bit, print time, , repeat. check again if left key still pressed. if is, move player left bit again, print time again, , repeat again. , on. never done loop until player lets go of left key - sit there moving player left (not can see it) , spamming console time.
the typical solution remove loops check key presses. keep if
s, move them outside event-handling loop. have this: (not actual code)
while(window open) { while(have event process) { process event } if(left key pressed) { move player left } if(right key pressed) { move player right } // , on update window }
you don't need update window inside event loop, way - unless event takes long time process (which shouldn't) you'll finish event loop quickly.
Comments
Post a Comment