Metody 3D grafiky (3. část, ovládání)

Ostatní jazyky Petr Lite 3D grafika Metody 3D grafiky (3. část, ovládání)

...pokračování z minulé lekce

V další lekci si rozebereme možnosti ovládání postavy ve hře. Použijeme k tomu postavičku mravence, kterou jsme získaly ze hry Kóta 236. Nebudeme se zabývat její animací, jen jednoduše použijeme ukazatele souřadnic postavy X a Z, směr otočení kolem osy Y a případně ještě sklon pohledu kolem osy X.

1. Základní ovládání

Při základním ovládání postavou pouze otáčíme do stran šipkami vlevo a vpravo, šipkami vpřed a vzad se pohybujeme. Při otáčení jen jednoduše přičítáme nebo odečítáme od úhlu otočení kolem osy Y konstantu (rychlost otáčení) vynásobenou uplynulým časem. Prvek uplynulý čas měří čas od minulého průchodu hlavní smyčkou (přesněji čas mezi dvěma naposledy vyrenderovanými snímky). Násobením rychlosti uplynulým časem zajistíme, že program poběží vždy stejnou rychlostí nezávisle na tom, jak je rychlý počítač a obsluha vykreslování grafiky.

Při pohybu vpřed a vzad vycházíme z nákresu podle následujícího obrázku. Jedná se o pohled na terén shora. Směr otočení kolem osy Y znamená otočení kolem svislé osy ve směru hodinových ručiček, přičemž nulový směr je ve směru kladné osy Z. Požadovanou vzdálenost jednoho úseku kroku vypočteme vynásobením uplynulého času konstantou rychlosti pohybu. Změnu souřadnice X poté zjistíme vynásobením úseku kroku funkcí sin úhlu otočení. Změnu souřadnice Z zjistíme vynásobením úseku kroku funkcí cos úhlu otočení.

Pro pohyb vpřed i vzad můžeme s výhodou použít jedinou funkci (parametrem bude rychlost pohybu), kterou budeme využívat i u ostatních způsobů ovládání. Kromě posunu souřadnic může funkce řešit i detekci kolize a přehrávání zvuku chůze.

2. Sklouzávání

Ovládání se sklouzáváním je rozšířením předešlého základního ovládání o detekci sklonu terénu. Sklon terénu způsobuje, že se postava pohybuje do kopce těžce (pomaleji) a z kopce snáze (zrychlí), případně do větších svahů se vůbec nedostane. Tím můžeme poměrně přirozeně řešit hranice terénu - hráč se nedostane mimo terén, protože mu brání strmé svahy.

V obsluze sklouzávání řešíme samostatně, nezávisle na sobě, sklouzávání ve směrech X a Z. Rozlišovací hranice pro sklouzávání takto sice nebude přesná, bude závislá na směru, ale vyhneme se určování směrníku sklonu terénu

Nejdříve si připravíme pomocnou proměnnou, udávající míru sklonu terénu v příslušném směru (X nebo Z). Nebudeme přesně řešit úhel sklonu, stačí nám jen jakési poměrné číslo. To vypočteme z rozdílů výšek terénu ve směrech mírně posunutých od aktuální pozice, rozdíl vynásobíme konstantou určující vliv sklouzávání.

Přesáhne-li míra sklouzávání určitou hranici, probíhá sklouzávání. V tom případě přičteme k dané souřadnici hodnotu míry sklonu vynásobenou uplynulým časem. Samozřejmě pokud se ke sklouzávání přidává vliv aktivity hráče, může hráč vyběhnout terén i při mírném sklouzávání. Při velkém svahu již vlastní aktivitou sklouzávání nevykoriguje a tak se do takového svahu již nedostane. Na maximální rychlost hráče je třeba dát pozor při návrhu míst, kam se hráč nemá dostat, aby nemohl nastat případ, že se hráč vyhrabe na nepatřičné místo například s využitím záchytných zlomů v terénu.

3. Rozšířené ovládání

Rozšířené ovládání je poněkud bohatší než základní. V tomto módu umožňujeme hráči měnit rychlost, drží-li současně při pohybu přesmykací klávesy Shift. Běžně klávesy Shift rychlost zvyšují. Aktivuje-li hráč přesmykač Caps Lock, bude rychlost trvale zvýšená a klávesy Shift ji budou naopak zpomalovat. Interně zajistíme obsluhu klávesy Shift tím způsobem, že si připravíme pomocné číslo použité jako násobek všech ostatních rychlostí, v závislosti na stisku Shift.

Klávesy vlevo a vpravo budeme obsluhovat běžným způsobem, tj. změnou směru otočení hráče. Je-li však současně s klávesami držen přesmykač Alt, neprovede se otočení, ale úkrok hráče do strany. Abychom mohli pro úkrok použít stejnou funkci jakou používáme i pro pohyb vpřed a vzad, použijeme malý úskok - hráče otočíme o 90° vlevo nebo vpravo, provedeme krok vpřed a hráče zas otočíme zpět.

Další doplňkovou funkcí rozšířeného ovládání je změna sklonu pohledu. Použije-li hráč klávesy PageUp nebo PageDown, naklání se pohledová kamera nahoru nebo dolů. Musíme přitom omezit maximální úhel náklonu, tedy jakési hraniční zarážky. Při řešení dorazů pamatujte na to, že úhly nemusí mít vždy jen rozsah -180° až +180°, stejně platné úhly jsou třeba i 270° (což odpovídá úhlu -90°). V ukázkovém programu je naklonění kamery měněno jen programově, proto se počítá s intervalem -180°až +180°. Pokud bychom však používali prvek úhlu X z Petra, ten je normalizovaný do rozsahu 0° až 360° což znamená, že záporné číslo se změní na velké číslo menší než 360°. Proto je třeba před kontrolou hranic buď úhel normalizovat do známého rozsahu nebo testovat hraniční intervaly pro více variant normalizace.

4. Kombinované ovládání

Při kombinovaném ovládání kombinujeme předešlé rozšířené ovládání klávesami spolu s ovládáním myší. Myší otáčíme pohledem hráče do stran a nahoru/dolů, zatímco šipkami vlevo a vpravo provádíme úkroky do stran. Tento mód je obzvláště vhodný pro rychlé akce, kde se hráč musí rychle otáčet, přesně zaměřovat a současně uskakovat do stran. I nadále zůstává hráči možnost otáčet se klávesami v případě, že spolu s šipkami vlevo a vpravo drží přesmykač Alt (tedy obráceně než v rozšířeném ovládání).

Při ovládání pohledu myší nelze vystačit pouze s vypnutím kurzoru myši a čtením aktuální souřadnice myši. Může se totiž stát, že kurzor myši se dostane ke kraji obrazovky a nehýbe se dál, čili ovládání by se v danou chvíli zarazilo. Proto nečteme absolutní souřadnici myši, ale změnu pozice myši od minule. Po každém načtení změny pozice myši vycentrujeme kurzor myši do středu okna. Tím zajistíme, že myš bude mít neustále dostatečnou rezervu pro výchylku.

Mód zachytávání myši (kdy je myš neustále centrována do středu okna a kurzor myši je vypnutý) je nepříjemný v tom, že po přepnutí na oknový mód není myš k dispozici a systém se tak stává těžko ovladatelný. Proto je nutné udělat přinejmenším takové opatření, že program bude zachytávat myš pouze v případě, kdy je program aktivní aplikací. Jestliže se uživatel přepne z programu jinam, musí se přestat myš zachytávat. Program si jen poznačí, že pozice myši je neznámá, aby po návratu pohled naráz neuskočil velkou změnou pozice myši. Pokud to charakter programu umožňuje, bylo by ideální zachytávat kurzor myši jen v případě celoobrazovkového módu, zatímco v oknovém módu tuto funkci nepoužívat, aby uživateli zůstala možnost ovládání okna myší.

Kurzor myši se při zachytávání myši zneviditelní předefinováním na průhledný obrázek. Není-li aplikace aktivní, je vhodné kurzoru myši navrátit jeho standardní vzhled. Není to nevyhnutelné, ale může být pro uživatele nepříjemné, pokud kurzorem pohybuje nad oknem aplikace a žádný kurzor nevidí. Resp. nemůže tak kurzor na obrazovce nikde najít.

Zaměřování myší je přímo nutností obzvláště v módu odstřelovače, kdy musí být zaměření přesné a citlivé.

5. Ovládání myší

U některých her může být výhodnější použít k ovládání postavy hráče (tedy avatara) myš, kdy klikáním na místa v terénu určujeme, kam se má postava přesunout nebo na koho zaútočit. Na rozdíl od běžných 2D aplikací nemůžeme u 3D projekce použít jednoduchý vztah mezi souřadnicí kurzoru myši a souřadnicí ukazatele v 3D prostoru. Musíme provést zpětnou projekci obrazovkové souřadnice myši do 3D souřadnic. Vzhledem ke složitosti je pro nás nereálné řešení průsečíku paprsku s jakoukoliv ploškou 3D světa, spokojíme se proto s kompromisem. Chceme především ovládat avatara, proto budeme uvažovat průsečík paprsku myši s rovinou terénu, ve které se avatar nachází. Výšku kamery proto budeme přepočítávat na výškovou hladinu, ve které se nachází avatar. Abychom se vyhnuli nejednoznačnostem při klikání myší (např. při kliknutí do výškově příliš odlišné oblasti, kdy tato metoda již nefunguje správně), budeme hráči zobrazovat v terénu indikační kurzor, aby věděl, kam program pokládá kurzor myši.

Situaci při vykreslování 3D grafiky si můžeme představit tak, jakoby před pohledovou kamerou byla umístěna skleněná deska, na kterou probíhá promítání scény. Této desce říkáme promítací rovina. Při pohybu myší po obrazovce můžeme vést z kamery ukazatelem myši pomyslný paprsek protínající promítací rovinu a rovinu terénu. Umíme vypočítat relativní pozici myši m vzhledem ke středu obrazovky (od souřadnice myši odečteme střed obrazovky a vydělíme zprůměrovaným rozměrem plochy). Relativní pozice myši m odpovídá úseku, o který je paprsek myši vzdálen od středového paprsku v místě promítací roviny. Známe vzdálenost promítací roviny p (máme na to ve 3D grafice prvek), takže máme všechny údaje a můžeme vypočítat úhel b, který svírá paprsek myši se středovým paprskem ve vertikálním směru. Můžeme k tomu použít funkci Petra úhel bodu, m bude souřadnicí x a p souřadnicí y.

Úhel a odpovídá sklonu kamery podle osy X. Odečtením úhlu paprsku myši b obdržíme úhel, o který je paprsek myši odkloněn od vodorovné roviny. Vzhledem k tomu, že známe výšku kamery nad terénem Y (přesněji nad rovinou terénu avatara) a spočítali jsme si již úhel, který svírá paprsek myši s terénem, můžeme odtud vypočítat vzdálenost průsečíku paprsku s terénem r (vynásobíme výšku kamery Y funkcí cotg úhlu a - b) a pohledovou vzdálenost průsečíku ke kameře d (vydělíme výšku kamery Y funkcí sin úhlu a - b). Zde musíme ošetřit případ, že kurzor myši je nad horizontem, tj úhel a - b je záporný - v tom případě průsečík omezíme na smysluplné velké číslo (např. rozměr terénu).

Podobně, jako jsme počítali úhel paprsku myši ve vertikálním směru, spočítáme úhel paprsku myši c v horizontálním směru. Horizontální souřadnici myši přepočteme na relativní souřadnici vzhledem ke středu promítací roviny a pomocí prvku úhel bodu vypočteme úhel c. Upozorňuji, že následující levý obrázek nepředstavuje pohled shora, ale pohled kolmý k rovině ohraničené paprskem myši. Paprsek myši může totiž směřovat i např. kolmo k zemi. Na základě vypočteného úhlu c a známé pozorovací vzdálenosti d (z předešlého výpočtu) můžeme vypočítat vzálenost e, o kterou je paprsek myši vzdálen od nevychýleného paprsku v místě průsečíku s terénem - vynásobením pohledové vzdálenosti d funkcí tg úhlu c. A také vypočteme opravenou skutečnou pozorovací vzdálenost d2 - vydělením pohledové vzdálenosti d funkcí cos úhlu c.

Na obrázku vpravo je pohled na stejný trojúhelník tvořený paprskem myši vychýleným ve směru X a nevychýleným paprskem, tentokrát ale tak, jak se promítá do roviny terénu. Vzdálenost průsečíku s terénem r již známe z dříve, nyní jsme vypočítali odklon e. Z těchto údajů můžeme vypočítat úhel f, který svírají odkloněný a neodkloněný paprsek myši v rovině terénu (pomocí funkce úhel bodu). Přičtením úhlu f ke směru otočení kamery kolem osy Y obdržíme reálný směr průsečiku paprsku myši s terénem f2. Posledním potřebným údajem je vzdálenost průsečíku paprsku myši s terénem od paty kamery q, který vypočteme z údajů e a r prvkem vzdálenost bodu.

 

Z úhlu a vzdálenosti průsečíku paprsku myši s terénem již snadno vypočteme souřadnice kurzoru myši v rovině terénu. Souřadnici X obdržíme přičtením násobku vzdálenosti průsečíku paprsku myši q a funkce sin úhlu paprsku f2 k souřadnici kamery X. Podobně souřadnici Z obdržíme přičtením násobku vzdálenosti průsečíku paprsku myši q a funkce cos úhlu paprsku f2 k souřadnici kamery Z. V daném místě vypočteme ještě výšku v terénu a umístíme tam zaměřovací kříž, který jsme vytvořili z objektu stěny položené do vodorovné roviny a opatřené poloprůhlednou texturou.

Aby zaměřovací kříž působil trochu zajímavěji a byl v terénu dobře patrný, zajistíme jeho animaci pomalým otáčením kolem osy Y. Vypnutím hloubkového testu zajistíme, že se kříž bude vykreslovat vždy a tak ho můžeme položit přesně na úroveň terénu (jinak by se s terénem prolínal a byl občas vidět a občas ne). Dále je dobré zajistit, aby kříž sledoval sklon terénu, tj. jakoby po terénu plaval. To zajistíme tím, že kříž budeme naklánět podle os X a Z. Pro každý ze směrů vypočteme sklon terénu tak, že zjistíme výšku terénu v bodech vychýlených o malý kousek od paprsku. Úhel, který svírá terén s vodorovnou rovinou, pak vypočteme z rozdílů výšek a vzdálenosti testovacích bodů prvkem úhel bodu. Vzdáleností testovacích bodů můžeme určovat plynulost přechodu sklonu kříže přes zlomové hrany terénu - čím bude vzdálenost větší, tím bude kříž přecházet přes hrany plynuleji.

Dále je dobré, měníme-li velikost zaměřovacího kříže tak, aby byl nezávislý na pohledové vzdálenosti. Nevypadalo by dobře, kdyby byl jednu chvíli příliš velký a jindy zas nepatrný. To provedeme tak, že měřítko zaměřovacího kříže budeme měnit přímo úměrně pohledové vzdálenosti průsečíku paprsku myši s rovinou d2 a nepřímo úměrně se vzdáleností promítací roviny p.

Posledním úkonem je pohyb avatara na dané místo, kam uživatel klikne kurzorem myši. To zajistíme úschovou souřadnic cílové pozice a nastavením příznaku přesunu avatara. V další obsluze (nezávislé již na aktivitě myši - tedy pokud hráč neklikne znovu na jiné místo) provádíme přesun na cílovou pozici, dokud je nastaven příznak přesunu. V každém okamžiku vypočteme zbývající vzdálenost k cíli a provedeme si zkušební zmenšení vzdálenosti o koeficient rychlosti vynásobený uplynulým časem. Pokud nová vzdálenost podteče pod nulu, bude v tomto kroku dosaženo cílové pozice. Vypneme příznak přesunu avatara a opravíme koeficient rychlosti tak, abychom vzdálenost kroku zmenšili na skutečnou zbývající vzdálenost. Vypočteme směr cíle a provedeme krok v daném směru.

6. Ovládání auta

Při ovládání dopravních prostředků je situace trochu složitější než u pěších avatarů. Především musíme řešit to, že dopravní prostředek se neumí rozjet a zastavit skokem, změna rychlosti musí být plynulá. A zpravidla se nemůže otáčet na místě.

Pro změnu rychlosti si budeme udržovat proměnnou udávající aktuální rychlost. Drží-li hráč šipku nahoru, budeme rychlost zvyšovat, což znamená přičítat koeficient zrychlení vynásobený uplynulým časem. Aby zrychlení vypadalo přirozeněji, nebudeme ho přičítat lineárně, ale ještě ho vynásobíme rozdílem aktuální rychlosti od maximální povolené rychlosti. Tím dosáhneme efektu, že auto bude zpočátku rychle nabírat rychlost, ale ve velkých rychlostech už bude zrychlovat jen pomalu, až do maximální dosažitelné rychlosti. Díky tomu nemusíme maximální rychlost omezovat. Naopak dosáhneme ještě zajímavého efektu, že pokud hráč z kopce přesáhne samospádem maximální rychlost a bude se snažit šipkou vpřed zrychlovat, naopak bude rychlost snižovat směrem k maximální rychlosti, tedy jakoby brzdil motorem.

Nedrží-li hráč šipku vpřed, bude auto samovolně zpomalovat, jen ale není-li dosaženo dané minimální rychlosti, kterou již považujeme za zastavení. Zpomalení provedeme lineárním odečítáním koeficientu samovolného zpomalení v závislosti na uplynulém čase.

Podobně jako zrychlení vpřed obsloužíme zpomalení (resp. pohyb vzad) a samovolné zpomalování při pohybu vzad, jen použijeme jiné hodnoty koeficientů.

Není-li dosaženo minimální rychlosti, kterou již považujeme za zastavení, provádíme v další obsluze jednak samotný pohyb danou rychlostí vpřed či vzad a jednak obsluhu zatáčení, kterou bychom neměli provádět v případě klidu. Tedy přesněji, jen u kolových dopravních prostředků. U pásových dopravních prostředků jako je např. tank je přirozené otáčení na místě.

Kromě běžného sklouzávání při velkém sklonu terénu bychom měli u auta obsluhovat i zrychlení a zpomalování závislé na sklonu terénu. Ze směru otočení auta vypočteme souřadnice kousek před autem. V příkladu jsme pro jednoduchost použili jednotkovou vzdálenost testovacího bodu. Zjistíme výšku terénu jednak v testovacím bodě před autem a jednak na aktuální souřadnici auta. Rozdíl výšek vynásobíme koeficientem vlivu terénu a vzniklý údaj jíž můžeme přičíst k aktuální rychlosti, samozřejmě vynásobený uplynulým časem. Korekci provádíme až od určité minimální hraniční hodnoty, aby se auto samovolně nerozjelo na mírném svahu.

Další věcí, kterou musíme u auta obsluhovat, je sledování sklonu terénu. Podobně jsme sledovali zaměřovací kříž při ovládání myší. Auto budeme naklánět podle os ve směrech X a Z. Z rozdílů výšek bodů, které leží od auta o určitou vzdálenost ve směrech osy Z, určíme úhel (pomocí prvku úhel bodu), který svírá terén s vodorovnou rovinou ve směru Z. O tento úhel otočíme auto podle osy X. Obdobně budeme obsluhovat druhou osu otáčení. Zjistíme výšky bodů posunutých do stran ve směrech osy X a vypočteným úhlem sklonu nastavíme sklon auta podle osy Z. Vzdálenost testovacích bodů ovlivňuje plynulost, s jakou auto mění sklon na hranách terénu. Testovací body by proto měly být v místech, kde se nacházejí kola auta.

7. Ovládání letadla

Opět jiný způsob ovládání bude u leteckého dopravního prostředku. Šipkami doleva a doprava ovládáme směrové kormidlo ovlivňující zatáčení. Rychlost zatáčení není okamžitá, ale mění se plynule. Nedrží-li hráč šipky vlevo a vpravo, směrové kormidlo se navrátí zpět do přímého směru a zatáčení se zas pomalu navrací do přímého směru. V závislosti na rychlosti zatáčení budeme měnit aktuální směr otočení letadla.

Šipkami nahoru a dolů řídíme rychlost stoupání a klesání nastavováním výškového kormidla. Stiskem šipky dolů přitáhneme řídicí páku, výškové kormidlo se zvedne a letadlo začne stoupat. Pomocí šipky dolů se naopak odtlačí řídicí páka, výškové kormidlo se sklopí a letadlo bude klesat. Rychlost stoupání opět neřídíme skokově, ale plynule v závislosti na čase. Čím déle budeme klávesu držet, tím rychleji bude letadlo stoupat či klesat. V závislosti na rychlosti stoupání měníme aktuální rychlost. Pokud letadlo stoupá nahoru, jeho rychlost se snižuje. Naopak klesáním se opět zvyšuje.

Z uvedených údajů odvozujeme animaci pohybu letadla. Rychlost stoupání ovlivňuje směr sklonu letadla podle lokální osy X. Rychlost zatáčení ovlivňuje směr sklonu letadla podle lokální osy Z. Pomocí rychlosti stoupání měníme výšku letadla (při kladné rychlosti stoupání se výška zvyšuje). Výšku v ukázkovém programu omezujeme tak, aby letadlo nebylo příliš vysoko nad terénem (aby neprolétlo oblaky) a také aby nebylo příliš nízko nad terénem, protože zde nepodporujeme přistávání ani kolizi s terénem.

.... pokračování příště


 

Stáhnout

Staženo 228x (6.09 MB)
Aplikace je včetně zdrojových kódů v jazyce Petr Lite (jsou obsaženy v EXE souboru, který lze v programu přímo otevřít)

 

  Aktivity (1)

Článek pro vás napsal Panda38
Avatar
Programátor C++, WinAPI, ASM.

Jak se ti líbí článek?
Celkem (1 hlasů) :
55555


 


Miniatura
Všechny články v sekci
3D grafika
Miniatura
Následující článek
Metody 3D grafiky (4. část, kamera)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!