Popis řešení

Detekce kolizí

Při řešení kolizí využívám vlastnosti toho, že všechny stěny jsou pravoúhlé a zabírají jeden celý čtverec na mapě. Při načítání mapy se vytvoří pole pravdivostních hodnot, které říká, je-li na daném místě zeď nebo není, viz následující obrázek.

Mapa

**************

*    *   P   *

*    *CBAS   *

*    *       *

*     D      *

*            *

**************

Zeď

11111111111111

10000100000001

10000100000001

10000100000001

10000000000001

10000000000001

11111111111111

Mapa a pole pravdivostních hodnot

Detekce kolize na “volném prostranství”

Při každém pokusu o pohyb se ještě před přesunem na novou pozici vypočítá cílová souřadnice, kde by se měl hráč objevit. Tato souřadnice v prostoru se přepočítá na souřadnice vzhledem k velikosti čtverců.

Pokud na cílové pozici není stěna, hráč je přesunut na novou pozici. Jestliže tam stěna je, bude nová souřadnice upravena tak, aby hráč nevstoupil do stěny. Pohyb ve směru, kde je stěna, bude vynulován a zachován bude pouze pohyb v kolmém směru – v tomto případě bude hráč po stěně klouzat a nedojde k jeho zaseknutí na místě.

Popis funkce algoritmu detekce kolize v rozích

Každý čtverec je rozdělen na čtyři sub-čtverce, jak je zobrazeno na obrázku. V každém sub-čtverci se kontroluje přítomnost stěny pouze v tom čtverci, který přísluší vrcholu sub-čtverce, na němž se hráč nachází.

Řešení samotných kolizí funguje stejně jako na “volném prostranství”. Podle matice pravdivostních hodnot se rozhodne, jestli tam je, či není stěna a jestli bude hráč vpuštěn na novou pozici.

Rozdělení čtverce
Rozdělení čtverce

Popis tříd a metod

package bludiste

Bludiste.java
Hlavní třída s metodou main(), přečte parametr příkazové řádky, pokud je -f, spustí se v celoobrazovkovém režimu. Volá třídy, které načítají mapu ze souboru a pak generují souřadnice bodů pro vykreslování čtverců.
Ctverec.java
Objekt, který reprezentuje jeden čtverec bludiště. Obsahuje vše, co je potřeba později při vykreslování při použití GL_QUADS, konkrétně souřadnice všech čtyř vrcholů, normálu a souřadnice pro textury.
GenerovaniBodu.java
Generuje souřadnice a z nich skládá čtverce, počítá příslušné normálové vektory. Vygenerované čtverce ukládá do kolekcí, které přísluší logickému celku (podlaha, strop, stěny).
KeyboardHandler.java
Handler pro zjiš»ování stisknutých kláves. Informace předává instanci třídy Renderer.
Konstanty.java
Konstanty ovlivňující vlastnosti výsledného vzhledu bludiště. Nastavuje se velikost políček bludiště, výška “očí” nad zemí a minimální odstup od stěny.
MouseMotionHandler.java
Zjiš»uje, zda bylo pohnuto myší. Pokud ano, zjistí o kolik a opět předá informaci instanci třídy Renderer.
NactiMapu.java
Čte mapu z textového souboru a ukládá výsledek do char pole.
Renderer.java
Hlavní třída pro zobrazení celé scény. Provádí se zde také vyhodnocení, o kolik se má hráč posunout každý frame z důvodu konstantní rychlosti pohybu bez ohledu na počet FPS.

Důležité metody třídy Renderer:

void update()
V případě, ze je stisknuta některá klávesa, posune hráče v daném směru.
void zakladniDetekceKolizi()
Řeší jednoduché kolize v ose X a Z.
void hledejObjekty()
Při pohybu v bludišti zjiš»uje, zda se na aktuální pozici hráče nachází objekt k sebrání.
void hledejTeleporty(GL gl, GLAutoDrawable glDrawable)
Podobně jako hledejObjekty(), ale hledá teleporty.
void detekceRohu()
Vyhodnocuje kolize v rozích.
void vykresliObjekty(GL gl, ArrayList<Ctverec> entita, int polohaTextury)
Vykresluje podlahu, strop a stěny pomocí GL_QUADS. Čtverce jsou uloženy v kolekci jako objekt Ctverec.
void display(GLAutoDrawable gLDrawable)
Provádí příslušné transformace, zapíná a vypíná světla a vykresluje nový frame.
void svetla(GL gl, GLAutoDrawable glDrawable)
Správné nastavení polohy světel při pohybu hráče.
void zobrazObjekty(GL gl, GLAutoDrawable glDrawable)
Vykresluje do bludiště objekty, které jsou určené ke sběru.
void zobrazTeleporty(GL gl, GLAutoDrawable glDrawable)
Vykresluje do mapy modely pro označení teleportů.
void nactiTextury(GL gl)
Načítá obrázky z disku, od každého obrázku se vytvoří tři stejné textury s různým filtrem – bez filtru, lineární filtrování a mipmapping. Textura je uložena jako ByteBuffer, načítat je možné textury v běžných formátech.
void init(GLAutoDrawable gLDrawable)
Inicializace a nastavení OpenGL zobrazení – způsob stínování, perspektivu, nastavení výchozí pozice hráče.
void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height)
Metoda je zavolána při změně velikosti okna a nastavuje perspektivu.
RozliseniObrazkovky.java
Informace o výchozí šířce a výšce okna, případně rozlišení při zobrazení na celou obrazovku.
RozmerBludiste.java
Uchovává informace o výchozích rozměrech bludiště.

package bludiste.ctverec

Bod.java, Normala.java, Vektor.java
Slouží k uchovávání souřadnic bodů v prostoru. Třídy jsou stejné, jiné názvy mají jen kvůli přehlednosti kódu.
SouradniceTextury.java
Uchovává u a v souřadnice pro textury.

package bludiste.utils (Třídy vycházejí z NeHe tutoriálů o OpenGL.)

BitmapLoader.java
Načítání bitmapových obrázků z disku.
GLDisplay.java
Vytváří vlastní zobrazovací plochu, do které se renderuje, nastavuje režimy zobrazení a obsahuje metody na přidávání handlerů na myš a klávesnici.
HelpOverlay.java
Vytváří výchozí nastavení pro renderování. Některé je později překryto nastavením, které je uvedeno v Renderer.java. Využívá se pro vypisování nápovědy na obrazovku.
ResourceRetriever.java
Otevírá soubory z JAR, aktuálního adresáře nebo z CLASSPASH, tuto třídu využívají BitmapLoader a TextureReader.
TextureReader.java
Načítání textur pro snadnější zpracování v OpenGL. Výška a šířka textur musí být mocnina 2, nejméně 64 pixelů. Z důvodu kompatibility se nedoporučuje používat větší textury než 256 pixelů.