Keyboard Events

Learn how to handle keyboard events with our own callbacks

Source Code

SFML Keyboard Events

Every time you play with your keyboard buttons, SFML will generate three types of Events

  • sf::Event::KeyPressed : Emitted when you press a button
  • sf::Event::KeyReleased : Emitted when you remove your finger from the button
  • sf::TextEntered : Emitted when a valid Unicode character is detected

What is a Unicode character ?  it’s any character representing a letter or a sign (punctuation, etc.) You can find a list here. The events KeyPressed and TextEntered seem similar but are actually different. For example, pressing SHIFT + A will generate the Unicode character uppercase “A”, so SFML will generate one event TextEntered but two events KeyPressed because two keys have been pressed SHIFT and A.

  • TextEntered is used when you write a text, for example writing the name of your hero or a password in your game
  • KeyPressed and KeyReleased are used for actual actions in your game, like running, jumping, etc.
The code below shows how to handle those three types of events. As you can see, the event TextEntered query only one information the Unicode character generated, while keyPressed and KeyReleased query five (5) information : the name (code) of the key that has been pressed/released and the state of the four (4) modifier buttons (ALT, SHIFT, CTRL, SYSTEM).
void handleEvent(const sf::Event& event)
{
    if(event.type == sf::Event::KeyPressed)
    {
        sf::Keyboard::Key key   =  event.key.code; //key name : A, B, SpaceBar etc.
        bool alt                =   event.key.alt;
        bool control            =   event.key.control;
        bool shift              =   event.key.shift;
        bool system             =   event.key.system;

        if(key == sf::Keyboard::A)
        {
            nero_log("Pressing on A");
        }
        if(key == sf::Keyboard::A && control)
        {
            nero_log("Pressing on CTRL + A");
        }
    }
    else if(event.type == sf::Event::KeyReleased)
    {
        sf::Keyboard::Key key   =  event.key.code; //key name : A, B, SpaceBar etc.
        bool alt                =   event.key.alt;
        bool control            =   event.key.control;
        bool shift              =   event.key.shift;
        bool system             =   event.key.system;
        if(key == sf::Keyboard::A)
        {
            nero_log("Releasing A");
        }
        if(key == sf::Keyboard::A && control)
        {
            nero_log("Releasing CTRL + A");
        }
    }
    if (event.type == sf::Event::TextEntered)
    {
        sf::Uint32 unicode = event.text.unicode;
        //Make sure the unicode character is valid (value should be below 128)
        if (event.text.unicode < 128)
        {
            std::string text = std::string(1, (static_cast(event.text.unicode)));
            nero_log(text);
        }
    }
}

Keyboard Events Callbacks

Now that you know how to use those 3 events, let’s improve our code by implementing our own callbacks. Instead of handling the Keyboard Events inside the Event Loop, we’ll use the two callbacks below

  • void onKeyboardButton(const sf::Keyboard::Key& key, const bool& isPressed, const ModifierKey& modifier)
  • void onTextEntered(const std::string& c)

The structure ModifierKey is used to store the four modifier keys states in one variable.

struct ModifierKey
{
    bool alt        = false;
    bool control    = false;
    bool shift      = false;
    bool system     = false;
};
void onKeyboardButton(const sf::Keyboard::Key& key, const bool& isPressed, const ModifierKey& modifier)
{
    //do something
        //key : name of the key (A, B, SpaceBar etc.)
        //isPressed : is the keyPressed or released ?
        //modifier : the state of the modifier keys (CTRL, ATL, SHIFT, SYSTEM)
}
void onTextEntered(const std::string& c)
{
    //do something
        // hero_name += c;
}

The code below shows our new improved handleEvent(event) method, pretty isn’t it !?

void handleEvent(const sf::Event& event)
{
    if(event.type == sf::Event::KeyPressed)
    {
        ModifierKey modifier;
        modifier.alt        = event.key.alt;
        modifier.control    = event.key.control;
        modifier.shift      = event.key.shift;
        modifier.system     = event.key.system;
        onKeyboardButton(event.key.code, true, modifier);
    }
    else if(event.type == sf::Event::KeyReleased)
    {
        ModifierKey modifier;
        modifier.alt        = event.key.alt;
        modifier.control    = event.key.control;
        modifier.shift      = event.key.shift;
        modifier.system     = event.key.system;
        onKeyboardButton(event.key.code, false, modifier);
    }
    if (event.type == sf::Event::TextEntered)
    {
        if (event.text.unicode < 128)
        {
            onTextEntered(std::string(1, (static_cast(event.text.unicode))));
        }
    }
}