Search code examples
c++sfmlkeypress

sfml - wait until key no longer pressed


I'm trying to make a var increase when i press a key, but there's one problem. As i hold that key it keeps on going, increasing my number (until i release the key of course). I wan't it to only add one for every press, even when i hold it.

Here's my code:

#include <SFML/Graphics.hpp>
#include <string>
#include <unistd.h>
#include <iostream>

using namespace std;
int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "-\\\\-(Game)-//-");
    sf::Style::Resize;

    int Selected = 1; 
    std::string s = std::to_string(Selected);

    window.setSize(sf::Vector2u(800, 600));
    sf::Font font;
    font.loadFromFile("DIMITRI_.TTF");

    sf::Event event;
    sf::Text Bplay("Play", font);
    Bplay.setCharacterSize(60);
    Bplay.setStyle(sf::Text::Underlined);
    Bplay.setPosition(50, 300);


    sf::Text Boption("Settings", font);
    Boption.setCharacterSize(60);
    Boption.setPosition(50, 400);

    sf::Text Ttitle1(s, font);
    Ttitle1.setCharacterSize(150);
    Ttitle1.setPosition(250, 50);
    sf::Text Ttitle2("Vault", font);
    Ttitle2.setCharacterSize(160);
    Ttitle2.setPosition(250, 200);

    while (window.isOpen())
    {

        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
            {
                    Selected++;
                    std::string s = std::to_string(Selected);
                    Ttitle1.setString(s);

            }
        while (window.pollEvent(event))
        {   
            if (event.type == sf::Event::Closed)
                window.close();


        }

        window.clear(sf::Color::Black);
        window.draw(Bplay);
        window.draw(Boption);
        window.draw(Ttitle1);
        window.draw(Ttitle2);
        window.display();
    }

    return 0;
}

All help is appreciated.


Solution

  • Make a variable that will hold if the user press or release a key

    bool onKeyHold = false; 
    

    So the algorithm would be:

    • Detect if he pressed a key.
    • if so, check if onKeyHold is false (you dont want to increment if hes holding a key)
    • if so, increment Selected then make onKeyHold true

    • Detect if he released a key. if so, make onKeyHold false.

    if you put them in code, it would be:

    bool onKeyHold = false; //create a variable that will hold if user press or release a key
    
    while (window.pollEvent(event))
    {   
        if ( event.type == sf::Event::KeyPressed ) check if user pressed a key
        { //if so
           if ( !onKeyHold ) // check if onKeyHold is false
           { //if so
               Selected++; // increment
           }
           onKeyHold = true; // make onKeyHold true
        }
        else if ( event.type == sf::Event::KeyReleased ) // check if user released a key
        { // if so
           onKeyHold = false; // make onKeyHold false
        } 
    }
    

    Edit:

    dont forget to check if the key is sf::Keyboard::Up or else this will work on every key available in SFML.

    the logic is:

    you will only increment if the user pressed a key which is what you want. if the user press a key you checked if onKeyHold is false ( user is not holding any key ), if that is false that means you just pressed a key and you are not holding it, because if you are holding a key it will trigger a key press event. so if you didnt check if onKeyHold is false then that would increment Selected every time you trigger a key press.