SFML community forums

Help => Window => Topic started by: traxys on September 28, 2014, 05:43:09 pm

Title: One action per isKeyPressed
Post by: traxys on September 28, 2014, 05:43:09 pm
Hello,

Here is the problem I have , I want to make something move from one lane to another , for that in a loop for window.isOpen() in the pollEvent loop I use this code , wich seemed pretty good to me :
            if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)){
                player.moveLane(UP);
            }
            if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)){
                player.moveLane(DOWN);
            }
 
But the problem here is that on the next occurence of the isOpen loop , it will try again to move , so the player moves twice , while pressing one key. So my idea was too make the player move one lane when pressing the key , how do you do that if this code doesn't work ?

And thhanks to anyone looking here :)
Title: Re: One action per isKeyPressed
Post by: G. on September 28, 2014, 06:30:29 pm
Use the keyPressed or keyReleased events (http://sfml-dev.org/tutorials/2.1/window-events.php#the-keypressed-and-keyreleased-events).
Title: Re: One action per isKeyPressed
Post by: dabbertorres on September 28, 2014, 06:47:00 pm
You can either use events like G suggested (best option imo), or you can disable key repeat with
window.setKeyRepeatEnabled(false);
Title: Re: One action per isKeyPressed
Post by: traxys on September 28, 2014, 07:15:46 pm
Thanks guys :)
I has was about the sf::EVenet::KeyPressed but did not understand how it worked , but did not see the tutorial either ><
Title: Re: One action per isKeyPressed
Post by: Hapax on September 28, 2014, 07:44:52 pm
You can either use events like G suggested (best option imo), or you can disable key repeat with
window.setKeyRepeatEnabled(false);
This stops the events repeating so would be used in conjuction with using events, not instead of using them.

Events (with key-repeating off if desired) does seem the better option, but you can also implement booleans to track whether it's been pressed and released since last time. This is extra work when you have events sat there, waiting for you though  ;)
Title: Re: One action per isKeyPressed
Post by: AlexAUT on September 28, 2014, 08:08:52 pm
Just in case you want to avoid events for your "realtime" controlls in a game you can save the old state and then check if it has changed, for example:

void checkReturnKey()
{
     static bool lastState = false;
     bool currentState = sf::Keyboard::isKeyPressed(sf::Keyboard::Return);

     if(!lastState && currentState)
          //Got pressed
     else if(lastState && !currentState)
          //Got released      

     lastState = currentState
}
 

With this code "Pressed"/"Released" will only get called 1time like with events.



AlexAUT
Title: Re: One action per isKeyPressed
Post by: wintertime on September 29, 2014, 08:19:26 pm
I would not simulate Events that way, because it still can fail to register short temporary key presses and releases and its a waste of CPU time and programmer effort, when there are Events already produced by SFML.
Title: Re: One action per isKeyPressed
Post by: AlexAUT on September 29, 2014, 08:45:31 pm
when there are Events already produced by SFML.

What if you have an application which doesn't have a window, or the user has to press a key before the window opens (stupid example  ;)).
When the windows is in background this would be the only way to check the keystates (without OS code or changing SFML)


AlexAUT
Title: Re: One action per isKeyPressed
Post by: Nexus on September 29, 2014, 08:53:01 pm
When the windows is in background this would be the only way to check the keystates (without OS code or changing SFML)
This is a very exotic scenario, the main use case that comes to my mind is a keylogger... And indeed I remember my anti-virus triggering an alert when global key input is caught, so it can be wise to deactivate real-time input when the window has no focus.

I agree with wintertime, events should be used for one-time transitions because they're exactly made for that.
Title: Re: One action per isKeyPressed
Post by: AlexAUT on September 29, 2014, 09:22:18 pm
This is a very exotic scenario, the main use case that comes to my mind is a keylogger...

Exotic scenario when the window is in background? Skype, Teamspeak have to check keystates when the window is in background (Push to talk, hotkeys), MSI afterburner to enable the overlay ingame, nearly every screen/game capturing application to start the capture, OBS/XSplit to change scenes, so mainly it's useful for hotkeys but i do not think they are exotic for mutlimedia applications ;)

AlexAUT
Title: Re: One action per isKeyPressed
Post by: Nexus on September 29, 2014, 09:33:32 pm
True, good examples. These applications however have in common that they require more rights than typical games (access to microphone, camera, other applications, current desktop screen, or... global keyboard input).

Your first post sounds like it would be a common approach to detect transitions between real-time input instead of using events directly, and given the initial problem description, I think it's very unlikely that this is actually needed. I just found the comment rather confusing without a notice of actual use cases, but it should be clear after your clarification ;)