Lekce 2 - SDL - Vytvoření okna a vstup od uživatele
V minulé lekci, SDL - Úvod a instalace, jsme založili nový projekt ve Visual Studiu využívající knihovnu SDL a v průběhu lekce vše správně nastavili.
V tomto díle si povíme něco o základním rozvržení aplikace, o vytvoření okna a o uživatelském vstupu.
Nekonečná smyčka
Každá hra, popřípadě aplikace, která něco vykresluje (a i samotný operační systém), pracuje ve smyčce, která je nekonečná.
int main() { LoadConfiguration(); Inicialization(); while(true) { ProcessInput(); UpdateScrene(); RenderScrene(); } Shutdown(); return; }
Na začátku načteme konfiguraci, poté inicializujeme základní systém, se kterým budeme pracovat. Načítání konfigurace není nutné, pokud žádnou nemáme. Aplikace následně vkročí do nekonečné smyčky, ve které se neustále opakují tři aktivity: získání vstupu, aktualizace scény a vykreslení.
Podle vstupu určíme, co se má dál odehrát - například při stisku určité klávesy posuneme hrdinu daným směrem. Při aktualizaci scény vypočítáme nový stav scény. Jako příklad uvedu polohu na mapě. Může to platit samozřejmě i pro jiné postavy, než postavu hráče. Ty se po mapě pohybují samostatně, nezávisle na vstupu od uživatele (ten ovládá jenom hlavního hrdinu). Novou polohu ostatních postav vypočítáme právě v této fázi.
V posledním kroku se scéna vykreslí. Většinou se vždy minimálně jeden objekt na mapě pohybuje, proto je nutné scénu vykreslit vždy. Počet cyklů za sekundu udává FPS (Frames per Second) – tedy počet vykreslení, které aplikace vykoná za sekundu. Jestliže v první fázi (při vstupu) zaregistrujeme událost, která aplikaci vypíná (stisknutí Esc nebo například vypnutí aplikace křížkem), vyskočíme z nekonečné smyčky a aplikaci vypneme. Tento scénář budeme využívat i my.
Inicializace SDL
K inicializaci SDL slouží funkce SDL_Init.
Prvním parametrem jsou flagy inicializující jednotlivé subsystémy SDL. Nás
bude zajímat především flag SDL_INIT_VIDEO
, který inicializuje
vykreslování a práci s grafikou. Pokud budeme chtít přidat další
subsystém, použijeme operátor OR
(SDL_INIT_VIDEO|SDL_INIT_AUDIO
). Subsystémy můžeme inicializovat
i postupně a to funkcí SDL_InitSubSystem,
která přijímá stejné parametry jako SDL_Init.
Pro vypnutí subsystému najdeme v SDL funkci SDL_QuitSubSubsystem. Přijímá stejné parametry jako SDL_Init. Pro vypnutí všech subsystémů použijeme SDL_Quit. Můžeme také ověřit, zda byl subsystém inicializován funkcí SDL_WasInit. Ta vrací bitovou masku. Pokud chceme zjistit, zda byl určitý systém inicializován, musíme použít binární AND (více v dokumentaci).
Vytvoření okna
Základní funkce je SDL_CreateWindow.
Prvním parametrem je ukazatel na řetězec. Podle tohoto textu se okno
pojmenuje. Další dva parametry jsou souřadnice levého horního rohu okna.
Zde můžeme použít konstanty SDL_WINDOWPOS_CENTERED
nebo
SDL_WINDOWPOS_UNDEFINED
. První konstanta vytvoří okno přesně
na středu obrazovky, druhá to poté nechá na operačním systému. Další
dvě souřadnice jsou šířka a výška okna. Posledním parametrem jsou opět
flagy, které
upravují vzhled okna. Najdeme zde flagy pro skryté okno
(SDL_WINDOW_HIDDEN
), minimalizované
(SDL_WINDOW_MINIMIZED
), okno s podporou OpenGL
(SDL_WINDOW_OPENGL
), fullscreen okno
(SDL_WINDOW_FULLSCREEN
) a další. Funkce vrací ukazatel na
strukturu SDL_Window
, se kterou budeme dále pracovat.
Pokud už okno nepotřebujeme, zrušíme jej unkcí SDL_DestroyWindow,
která se o vše postará. Protože se jedná o knihovnu určenou pro C,
žádné objekty se neruší voláním delete
.
Kromě toho máme k dispozici funkce pro manipulaci s oknem. Můžeme nastavovat jeho světlost, pozici, maximální a minimální velikost, FullScreen a podobné věci. Pro více informací přesměruji na dokumentaci. Tyto funkce zatím nebudeme potřebovat.
Získání vstupu od uživatele
Pro uživatelský vstup je situace trochu komplikovaná, protože každá událost má jiná data, která přenáší. Například pro stisk tlačítka myši bude mít událost údaje o pozici, kde byla myš stisknuta, zatímco u stisku klávesy bude jediný údaj o klávese, která byla stisknuta. Z toho plyne, že každá událost má vlastní strukturu.
SDL nám to naštěstí trochu usnadňuje - definuje union (typ, který může nabývat jeden z nadefinovaných typů), a zároveň každá struktura má proměnnou type, ve které je uložen jeden z enumerátoru SDL_EventType. Onen výše zmíněný union je SDL_Event, který v sobě obsahuje všechny struktury událostí. To znamená, že SDL_Event obsahuje vždy atribut type, na základě kterého se může program dále rozhodovat, jak bude s daty pracovat.
Získání událostí
Základní funkcí je SDL_PollEvent,
který uloží do prvního parametru typu SDL_Event *
první
událost ve frontě. Zároveň vrací hodnotu 1, pokud byla událost předána.
Pokud už žádné další události ve frontě nejsou, vrátí 0. Z toho lze
lehce odvodit, že pokud chceme vyzvednou všechny události ve frontě,
zavoláme tuto funkci v cyklu.
SDL_Event * Event = new SDL_Event; while (SDL_PollEvent(event)) { if (event->type == SDL_QUIT) EndGame(); else if (event->type == SDL_KEYDOWN) MovePlayer(); }
Typy událostí
Událost typu SDL_QUIT
volá operační systém a aplikace by na
něj měla vždy reagovat. Jedná se právě o zavření okna křížkem, Alt+F4
a podobné způsoby.
Dalšími důležitými událostmi jsou:
SDL_MOUSEBUTTON
- registruje stisk tlačítka myši
SDL_KEYDOWN
- registruje stisk klávesy
SDL_MOUSEMOTION
– registruje pohyb myši
Události budou podrobněji probrány v jednom z následujících dílů.
Spojme vše dohromady
Jaký tedy bude návrh konečného programu? Ze začátku inicializujeme SDL, poté vytvoříme nekonečnou smyčku a jestliže zachytíme událost typu SDL_QUIT, tak aplikaci ukončíme.
Příště, v lekci SDL - Základy vykreslování, si na obrazovku vykreslíme obdélník a podle akcí uživatele jím budeme pohybovat.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkamiStaženo 1050x (3.34 MB)