⬆️ ⬇️

3.2 Event handling





From the translator: this article is the tenth in the translation cycle of the official SFML library guide. Past article can be found here. This series of articles aims to provide people who do not know the original language the opportunity to get acquainted with this library. SFML is a simple and cross-platform multimedia library. SFML provides a simple interface for developing games and other multimedia applications. The original article can be found here . Let's start.



Table of contents:
0.1 Introduction



1. Getting Started

')

  1. SFML and Visual Studio
  2. SFML and Code :: Blocks (MinGW)
  3. SFML and Linux
  4. SFML and Xcode (Mac OS X)
  5. Compiling SFML with CMake


2. System Module



  1. Processing time
  2. Streams
  3. Work with custom data streams


3. Window Module



  1. Opening and managing windows
  2. Event handling
  3. Work with the keyboard, mouse and joysticks
  4. Using OpenGL


4. Graphics Module



  1. Drawing 2D objects
  2. Sprites and textures
  3. Text and Fonts
  4. Forms
  5. Designing your own objects using arrays of vertices
  6. Position, Rotation, Scale: Transform Objects
  7. Adding special effects with shaders
  8. 2D camera control and view


5. Audio module



  1. Playing sounds and music
  2. Audio recording
  3. Custom audio streams
  4. Spitalization: sounds in 3D


6. Network module



  1. Socket communication
  2. Use and Expansion Packages
  3. Web requests using HTTP
  4. File Transfer Using FTP




Introduction



This article provides a detailed list of events and explains how to handle these events.



Type sf :: event



Before a detailed analysis of event processing, it is important to understand what the sf :: Event type is and how to use it correctly. sf :: Event consists of a union that stores the type of event, and auxiliary functions and members. An available member of the association corresponds to one or more members of the class, for example, event.key corresponds to the KeyPressed event. Attempting to handle any other members will result in unspecified behavior. Never attempt to handle an event that has not occurred.



You can initialize an sf :: Event instance with the pollEvent (or waitEvent ) function of the sf :: Window class. Only these two functions can initialize an sf :: Event instance.



For clarity, here’s what a typical event loop looks like:



 sf::Event event; //   ,  ... while (window.pollEvent(event)) { //   ... switch (event.type) { //   case sf::Event::Closed: window.close(); break; //   case sf::Event::KeyPressed: ... break; //       default: break; } } 


Re-read the paragraph above and make sure you understand everything. The sf :: Event class causes many problems for novice programmers.



Well, now we know how events are represented in SFML, it’s time to find out what each event means.



Closed event



The sf::Event::Closed triggered when the user wants to close the window using any of the methods provided by the window manager (the close button, keyboard macros, and so on). This event provides information that the user attempted to close the window; it is not yet closed.



Usually, in response to this event, the code calls window.close() to close the window. However, you can do something else, for example, save the current state of the application or ask the user what to do. If you do nothing in response to this event, the window will remain open.



The class member associated with this event does not exist.



 if (event.type == sf::Event::Closed) window.close(); 


Resized event



The sf::Event::Resized fires when the window is resized. Either as a result of user action, or programmatically, after calling window.setSize .



You can use this event to adjust the display settings: the viewport if you are using OpenGL directly, or the current viewpoint if you are using sfml-graphics .



The class member associated with this event is called event.size and contains the new window size.



 if (event.type == sf::Event::Resized) { std::cout << "new width: " << event.size.width << std::endl; std::cout << "new height: " << event.size.height << std::endl; } 


Events LostFocus and GainedFocus



The sf::Event::LostFocus and sf::Event::GainedFocus triggered when the window has lost / acquired focus; this happens when the user changes the current active window. When a window loses focus, it does not receive keyboard events.



This event can be used, for example, to pause the game when the window is inactive.



The class member associated with this event does not exist.



 if (event.type == sf::Event::LostFocus) myGame.pause(); if (event.type == sf::Event::GainedFocus) myGame.resume(); 


TextEntered Events



The sf::Event::TextEntered triggered when a character entry occurs. This is not a KeyPressed : TextEntered triggered when the user enters a character that can be displayed. For example, pressing the '^' and 'e' on the French keyboard will result in two KeyPressed events and only one TextEntered containing a 'ĂŞ' character. This works for all input methods provided by the operating system.



This event is typically used to capture user input in a text field.



The class member associated with this event is called event.text and contains the Unicode character number of the character entered. You can put this value in sf :: String , or cast it to type char after making sure that this character lies in the range of ASCII characters (0 - 127).



 if (event.type == sf::Event::TextEntered) { if (event.text.unicode < 128) std::cout << "ASCII character typed: " << static_cast<char>(event.text.unicode) << std::endl; } 


Many programmers use the KeyPressed event to handle user input and use crazy algorithms to process user input, which they try to interpret all possible key combinations. Do not do this!



KeyPressed and KeyReleased events



The sf::Event::KeyPressed and sf::Event::KeyReleased events work when a key on the keyboard is pressed / released.



If the key is clamped, KeyPressed events will be generated at specific intervals set by the operating system (i.e. the same delay that applies when you enter text in the editor). To undo the repetition of KeyPressed events, you can call window.setKeyRepeatEnabled(false) . Obviously, the KeyReleased event never repeats.



These events can be used if you want to trigger an action exactly once when the key is pressed or released, for example, to make the character jump.



Sometimes people try to use the KeyPressed event to implement smooth motion. This does not lead to the expected effect, because this event is generated at a certain interval. To realize smooth motion using events, you must use a Boolean value set by KeyPressed and KeyReleased ; movement must be carried out until this logical value is established.



Other (simpler) ways to implement a smooth movement, using keyboard water using sf :: Keyboard (see the dedicated article ).



The class member associated with this event is called event.key and contains the key of the pressed / depressed symbol, as well as the current state of the modifier keys (alt, control, shift, system).



 if (event.type == sf::Event::KeyPressed) { if (event.key.code == sf::Keyboard::Escape) { std::cout << "the escape key was pressed" << std::endl; std::cout << "control:" << event.key.control << std::endl; std::cout << "alt:" << event.key.alt << std::endl; std::cout << "shift:" << event.key.shift << std::endl; std::cout << "system:" << event.key.system << std::endl; } } 


Remember that some keys are specific to the operating system; handling these keys leads to undefined behavior. For example, the F10 key in Windows, which changes the focus, or the F12 key, which launches the debugger when using Visual Studio. This problem will be solved in future versions of SFML.



MouseWheelMoved event



The sf::Event::MouseWheelMoved is deprecated and has been aborted in SFML 2.3. Use MouseWheelScrolled .



MouseWheelScrolled event



The sf::Event::MouseWheelScrolled when the mouse wheel moves up, down, or sideways (if supported by the mouse).



The class member associated with this event is called event.mouseWheelScroll and contains the number of ticks that the wheel has shifted to, the orientation of the wheel movement and the current position of the mouse cursor.



 if (event.type == sf::Event::MouseWheelScrolled) { if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel) std::cout << "wheel type: vertical" << std::endl; else if (event.mouseWheelScroll.wheel == sf::Mouse::HorizontalWheel) std::cout << "wheel type: horizontal" << std::endl; else std::cout << "wheel type: unknown" << std::endl; std::cout << "wheel movement: " << event.mouseWheelScroll.delta << std::endl; std::cout << "mouse x: " << event.mouseWheelScroll.x << std::endl; std::cout << "mouse y: " << event.mouseWheelScroll.y << std::endl; } 


MouseButtonPressed and MouseButtonReleased Events



The sf::Event::MouseButtonPressed and sf::Event::MouseButtonReleased triggered when the mouse button is pressed / released.



SFML supports 5 mouse buttons: left, right, middle (mouse wheel), extra # 1 and extra # 2 (buttons on the side).



The class member associated with this event is called event.mouseButton and contains the key of the pressed / pressed button and the position of the mouse cursor.



 if (event.type == sf::Event::MouseButtonPressed) { if (event.mouseButton.button == sf::Mouse::Right) { std::cout << "the right button was pressed" << std::endl; std::cout << "mouse x: " << event.mouseButton.x << std::endl; std::cout << "mouse y: " << event.mouseButton.y << std::endl; } } 


MouseMoved event



The sf::Event::MouseMoved triggered when the mouse cursor moves inside a window.



This event is triggered even if the window is out of focus. However, the triggering occurs only when the mouse cursor moves only within the inner region of the window (the header and borders do not enter the inner window),



The class member associated with this event is called event.mouseMove and contains the position of the mouse cursor relative to the window.



 if (event.type == sf::Event::MouseMoved) { std::cout << "new mouse x: " << event.mouseMove.x << std::endl; std::cout << "new mouse y: " << event.mouseMove.y << std::endl; } 




MouseEntered and MouseLeft Events



The sf::Event::MouseEntered and sf::Event::MouseLeft triggered when the mouse cursor enters or leaves the window.



The class member associated with this event does not exist.



 if (event.type == sf::Event::MouseEntered) std::cout << "the mouse cursor has entered the window" << std::endl; if (event.type == sf::Event::MouseLeft) std::cout << "the mouse cursor has left the window" << std::endl; 


Events JoystickButtonPressed and JoystickButtonReleased



The sf::Event::JoystickButtonPressed and sf::Event::JoystickButtonReleased triggered when the gamepad button is pressed / released.



SFML supports 8 joysticks and 32 buttons.



The class member associated with this event is called event.joystickButton and contains the joystick identifier and the index of the pressed / depressed button.



 if (event.type == sf::Event::JoystickButtonPressed) { std::cout << "joystick button pressed!" << std::endl; std::cout << "joystick id: " << event.joystickButton.joystickId << std::endl; std::cout << "button: " << event.joystickButton.button << std::endl; } 


Event JoystickMoved



The sf::Event::JoystickMoved triggered when the gamepad stick moves.



Joystick sticks are usually very sensitive, which is why SFML uses a detection threshold to avoid constant JoystickMoved triggering. This threshold can be changed by calling the Window::setJoystickThreshold .



SFML supports 8 joystick sticks: X, Y, Z, R, U, V, POV X and POV Y. How it interacts with a gamepad depends on the driver of this gamepad.



The class member associated with this event is called event.joystickMove and contains the joystick ID, the stick name and its current position (in the interval [-100, 100]).



 if (event.type == sf::Event::JoystickMoved) { if (event.joystickMove.axis == sf::Joystick::X) { std::cout << "X axis moved!" << std::endl; std::cout << "joystick id: " << event.joystickMove.joystickId << std::endl; std::cout << "new position: " << event.joystickMove.position << std::endl; } } 


Events JoystickConnected and JoystickDisconnected



The sf::Event::JoystickConnected and sf::Event::JoystickDisconnected triggered when the joystick joins / detaches.



The member class associated with this event is called event.joystickConnect and contains the identifier of the connected / disconnected joystick.



 if (event.type == sf::Event::JoystickConnected) std::cout << "joystick connected: " << event.joystickConnect.joystickId << std::endl; if (event.type == sf::Event::JoystickDisconnected) std::cout << "joystick disconnected: " << event.joystickConnect.joystickId << std::endl; 


Next article: Working with the keyboard, mouse and joysticks.

Source: https://habr.com/ru/post/280153/



All Articles