Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Detecting if a key was pressed, not if it is always down  (Read 24171 times)

0 Members and 1 Guest are viewing this topic.

SkullBlade

  • Newbie
  • *
  • Posts: 5
    • View Profile
Detecting if a key was pressed, not if it is always down
« on: December 09, 2009, 09:17:48 pm »
Hello, I've been using SFML for a little while and I decided to create a DDR-like game with it.

The problem I have is, what is the best way to detect when a key has been pressed, and only execute the code which should be executed when the key has been pressed once?

The problem I have is that as long as the key is down, the game keeps executing the input code. (Basically to set the scale of a sprite to 0.5, otherwise it should go back up to 1). However the sprite always seems to stay at 0.5 when the key is held down, I want it to go to 0.5 when the key is first pressed and then return to 1.0.

Here is the code I'm using:

Code: [Select]

int NoteReceptors::CheckInput(sf::RenderWindow &Window)
{
const sf::Input& GetInput = Window.GetInput();

if (GetInput.IsKeyDown(sf::Key::Left) && TickL == 0)
{
TickL = 1;
ScaleL = 0.6;

}
else
{
TickL = 0;
}


As said above, it does not work, the code runs as if TickL didn't exist, therefore the scale always stays at 0.5 as long as the key is pressed.

I hope I explained it well enough, what I want to know is how to set it to 0.5 only when the key is first pressed, and then return to 1 even if the key is held down.

I also have
Code: [Select]
if (ScaleL < 1) {ScaleL += 0.1;} in the main loop so it does increase when the key is released.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Detecting if a key was pressed, not if it is always down
« Reply #1 on: December 09, 2009, 09:28:15 pm »
For that purpose, you can use the SFML event system. Poll for events, and if the received event is a KeyEvent, perform the desired actions. Real time input is useful if you want to check whether a key is currently being pressed or not.

These steps are explained in the tutorials, you should read them.
http://www.sfml-dev.org/tutorials/1.6/window-events.php
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Detecting if a key was pressed, not if it is always down
« Reply #2 on: December 09, 2009, 09:28:27 pm »
You must use events, not sf::Input. See sf::Event and Window.GetEvent.
Laurent Gomila - SFML developer

SkullBlade

  • Newbie
  • *
  • Posts: 5
    • View Profile
Detecting if a key was pressed, not if it is always down
« Reply #3 on: December 09, 2009, 09:41:36 pm »
Oh okay, I will try that, thanks for the help.

SkullBlade

  • Newbie
  • *
  • Posts: 5
    • View Profile
Detecting if a key was pressed, not if it is always down
« Reply #4 on: December 09, 2009, 10:12:32 pm »
That got it working, thank you both for the help. :)

Adi

  • Newbie
  • *
  • Posts: 3
    • View Profile
Detecting if a key was pressed, not if it is always down
« Reply #5 on: December 09, 2009, 10:46:04 pm »
There is also other way to this, without using events. Which is useful when your design makes it impossible or very hard to use events for such tasks.

You can just save previous key state and check if it was released in previous check.

Example:
Code: [Select]
//Should be declared in some warm and safe place (as class member or before main loop :P)
bool previousKeyState;
//Of course name of variable should have some more meaning like prevousShootKeyState etc.

//Actual code
const sf::Input& GetInput = Window.GetInput();

if(GetInput.IsKeyDown(sf::Key::Left) && !previousKeyState)
{
//The Key has been pressed after being released

/*Add some magic code*/

}
else
{
//The Key is not pressed or is being held hostage

/*Some other magic code*/

}

previousKeyState = GetInput.IsKeyDown(sf::Key::Left);
/*I assume this is acceptable because key states are stored as bool[] so compiler will optimize it as an inline and key state can change only after calling GetEvent*/

//End of presentation

SkullBlade

  • Newbie
  • *
  • Posts: 5
    • View Profile
Detecting if a key was pressed, not if it is always down
« Reply #6 on: December 26, 2009, 11:59:54 pm »
Thanks for the help all, it seems to be partially working.

I'm currently using the Events system, but now if the left key is held down, it will work correctly for a few seconds and then repeatedly starts firing off. Is there a way to stop that from happening with the Events system?

It seems to be exactly the same as when a letter is held in a word processor.

Adi: Thanks, but that code doesn't work either, it does near enough the exact same thing as my original code.

Sorry if this is a stupid problem, but I am pretty new to SFML.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Detecting if a key was pressed, not if it is always down
« Reply #7 on: December 27, 2009, 12:32:54 am »
Use Window.EnableKeyRepeat(false).
Laurent Gomila - SFML developer

SkullBlade

  • Newbie
  • *
  • Posts: 5
    • View Profile
Detecting if a key was pressed, not if it is always down
« Reply #8 on: December 27, 2009, 01:34:27 am »
Thank you all for the quick responses, it is now working perfectly. :)

RetroX

  • Newbie
  • *
  • Posts: 13
    • View Profile
Detecting if a key was pressed, not if it is always down
« Reply #9 on: March 07, 2010, 03:51:40 am »
Just one thing that could be used as an alternate solution: make a bool that is set to true or false depending on whether or not the key is detected as being pressed with sf::Input, and then it is considered "pressed" once the key is pressed when it was not previously pressed in the last frame.

For example:
Code: [Select]
bool spacepressed=false'
const sf::Input &input=App.GetInput();
...
 // Do something on space bar press
 if (input.IsKeyDown(sf::Key::Space) && !spacepressed)
  {
  ...
  spacepressed=true;
  }
...

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Detecting if a key was pressed, not if it is always down
« Reply #10 on: March 07, 2010, 12:33:47 pm »
Quote from: "RetroX"
Just one thing that could be used as an alternate solution: make a bool that is set to true or false depending on whether or not the key is detected as being pressed with sf::Input, and then it is considered "pressed" once the key is pressed when it was not previously pressed in the last frame.
Ok, but I don't really see a reason to do that, since SFML already provides this functionality. The approach might become ugly as soon as there is more than one key-press being checked.

By the way, I think the topic isn't relevant anymore. The last post was written in 2009.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

RetroX

  • Newbie
  • *
  • Posts: 13
    • View Profile
Detecting if a key was pressed, not if it is always down
« Reply #11 on: March 07, 2010, 06:57:13 pm »
...oh, wow.  I didn't realize that this topic was that old.  Sorry about that.