📜 ⬆️ ⬇️

SDL 2.0 Lesson Cycle: Lesson 4 - Event Handling

SDL2

From the translator:

This is a continuation of a series of translations of tutorials from Twinklebear, originally available here . The translation is partly voluntary and may contain minor corrections or additions from the translator. The first two lessons are translated by InvalidPointer . Drawings from the original article are localized with maximum preservation of the author’s style.

List of lessons:



Event handling


In this lesson, we will learn the basics of getting user input, and for simplicity, we will take any user action as an escape attempt to shut down the program. SDL uses the SDL_Event structure and functions to retrieve events from the event queue, such as SDL_PollEvent, to obtain information about events. Code written in this lesson is based on the results of the previous lesson .

But for a start, let's change the picture in the center of the screen so that the user who first saw your program understands what it does and what is required of it.


The author's little man is saved

The simplest main loop


We will add the main loop to the program, which will make the program work until the user wants to exit (and notifies the program about it in the form available to it, of course), instead of a fixed delay, as was the case in previous lessons. Here is the approximate structure of such a cycle:

while (!quit) // Пока не вышли, делаем следующее: { // Считываем пользовательский ввод и обрабатываем его // Рисуем что-нибудь на экране } 


SDL event queue


To properly use the SDL event system, we will need at least a minimal understanding of its operation. When the SDL receives an event from the operating system, it places it at the end of the queue, after all other events that were received earlier but have not yet been extracted from there by the program. If, after launching the program, we would alternately resize the window, click on it with the mouse and press a key, the event queue would look like this:


When we call SDL_PollEvent, we get an event from the head of the queue, the oldest of the remaining ones. Receiving events from a queue using SDL_PollEvent removes them from there, to avoid this, you can “peep” the event using the SDL_PeepEvents function with the SDL_PEEKEVENT flag set. More information about this feature can be found in the documentation, as part of this article, it is not required (and you, most likely, also) and therefore will not be considered.

Event handling


In the main loop, we want to receive all the available events that came after drawing the previous frame, and process them. To do this, it is enough to place the SDL_PollEvent in a while loop condition, since it returns 1 if it received an event, and 0 if nothing is received. Since all that the program does is complete its work at certain events, it will suffice to use a boolean variable (bool quit), denoting whether we want to end the program or not, and set its value to true when these events are received.

 // e - это переменная типа SDL_Event, которую стоит объявить до главного цикла while (SDL_PollEvent(&e)) { // Если пользователь попытался закрыть окно if (e.type == SDL_QUIT) { quit = true; } // Если пользователь нажал клавишу на клавиатуре if (e.type == SDL_KEYDOWN) { quit = true; } // Если пользователь щёлкнул мышью if (e.type == SDL_MOUSEBUTTONDOWN) { quit = true; } } 


This loop should be placed inside the main loop of the application.
An SDL_QUIT event occurs when the user closes the window, SDL_KEYDOWN — when a key is pressed on the keyboard (and comes many, many times while it is held, just as letters repeat when the key is held while the text is being printed), and an SDL_MOUSEBUTTONDOWN event — when mouse click. These are just some of the events that your application can receive - and the total SDL can receive more than 20 types of events that this article cannot cover, by itself, is not strong enough , therefore you should read about them in the documentation for SDL_Event

Completion of the main cycle


With event processing finished, but in the main loop there is not enough of one more part - scene display. We have already considered this topic in previous lessons, it remains only to apply this knowledge, and the main cycle will take the following form:

 // Структура события SDL_Event e; // Флаг выхода bool quit = false; while (!quit) { // Обработка событий while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { quit = true; } if (e.type == SDL_KEYDOWN) { quit = true; } if (e.type == SDL_MOUSEBUTTONDOWN) { quit = true; } } // Отображение сцены SDL_RenderClear(renderer); renderTexture(image, renderer, x, y); SDL_RenderPresent(renderer); } 


This program will work forever. Well, or at least until the user politely asks her to stop. After starting the program, pressing the button with a cross, pressing any key on the keyboard or clicking the mouse inside the window should lead to the completion of its work. Until then, it will simply redraw the contents of the window all the time.

Addition from the translator: the program in the form in which it is, most likely, will consume all of the available processor resources, fully loading one core. It would be rational to add a small delay (1-5 ms) to the end of the main loop using SDL_Delay so that in the absence of events the program frees up the processor for other programs. This does not apply to heavy games, which already require all available resources, when at 100fps to spend 100ms every second to wait is an unaffordable luxury.

The end of the fourth lesson


That came to an end the next lesson. See you in lesson 5: Sampling from the texture atlas

Homework: try adding motion pictures, for example, using arrows.

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