Keyboard Events
Learn how to handle keyboard events with our own callbacks
Source Code
- The code for this tutorial can be found on Github : Learn SFML – Keyboard Event Scene
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.
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)))); } } }