Update home authored by Svoboda, Jan's avatar Svoboda, Jan
......@@ -2,6 +2,8 @@
https://cw.fel.cvut.cz/b212/courses/b0b36pjv/semestral/herni_engine Semestrální práce dle zadání 2022 Letní semestr PJV FEL CVUT
K vytvoření této semestrální práce byla použita grafická knihovna **JavaFX**
* Vytvořte herní engine pro realtime RPG Hru. V této hře bude hráč ovládat hrdinu, který bude procházet jednotlivé levely, v nichž bude sbírat předměty a bojovat s příšerami. Obecné zadání semestrální práce:
* Práce je vyvíjena za pomoci verzovacího systému GIT. Ve wiki bude udržována zvláštní stránka s odhadem pracnosti jednotlivých částí práce a rozdělení úkolů každého z týmu.
......@@ -27,7 +29,7 @@ https://cw.fel.cvut.cz/b212/courses/b0b36pjv/semestral/herni_engine Semestráln
* Hrdina bude umět pomocí sebraných předmětů interagovat s dalšími předměty (otevře dveře klíčem, rozbije truhlu palicí atd.).
* Herní engine musí být vybaven GUI.
# **Uživatelský manuál**
# **Uživatelský manuál (**[**link**](https://gitlab.fel.cvut.cz/svobo114/java-rpg-game-pjv/-/wikis/Dokumentace/U%C5%BEivatelsk%C3%BD-manu%C3%A1l)**)**
**Menu:**\
V menu jsou 3 tlačítka: "**New Game**" (zapne novou hru = načte novou hru ze "default.save"), "**Load Last Save**" (načte poslední uloženou hru z "last.save") a "**Quit**" (okamžitě ukončí hru). Pro pokračování do vlastní hry je třeba zmáčknout jedno z prvních dvou tlačítek.
......@@ -52,4 +54,58 @@ Pro uložení stačí zmáčknout "Save Game" v herním menu. Automaticky se př
**Flow:** Po zapnutí hry je třeba si vybrat, jestli chci novou hru, nebo načíst poslední uloženou hru (I pokud je hra čerstvě stažena, je tam uložená "minulá" hra, kterou jsem si já rozehrál). Otevře se mi nové herní okno, kde vidím panáčka, mapu na pozadí a animované moby pobíhající okolo. Můžu vyzkoušet Inventář "I" , kde můžu vybavit předměty (lze si povšimnout, že po vybavení meče značně naroste poškození dané mobům okolo (kostlivci, slimáci). Pokud jsem dostatečně blízko u truhly, na kterou mám klíč, můžu ji otevřít pomocí "E". Pokud nemám klíč, nebo nejsem dost blízko, truhla se neotevře. Momentálně jsou na mapě 2 truhly, můžu otevřít tu vzdálenější, a vzít z ní klíč, který otevře tu více "vlevo". V té se nachází nejlepší meč, který značně zvedne poškození, které hráč dává. Po projití po mapě můžu hru vypnout, nebo ji uložit. když ji uložím, můžu ji pak načíst z hlavního menu. Abych se dostal do menu, musím hru vypnout a zapnout.
# **Programátorský Popis**
\ No newline at end of file
# **Programátorský Popis (**[**link**](https://gitlab.fel.cvut.cz/svobo114/java-rpg-game-pjv/-/wikis/Dokumentace/T%C5%99%C3%ADdy-a-Package)**)**
Níže se pokusím nastínit jaké **klíčové** třídy se mi starají o běh celé hry a vysvětlit, jak spolu ony třídy interagují při běžném běhu programu. Děleno po balíčcích. (**klíčové** ve smyslu- důležité pro běh programu, ne factory třídy co vytváření GUI, ani třídy itemů, jenž jsou tam pouze pro konkrétní náplň hry, ale spíš třídy co řeší kolize, grafiku, přepínání scén etc.).
Už názvy balíků naznačují, že jsem se snažil navrhnout program dle Model-View-Controller, což se né-vždy povedlo přesně oddělit. Například můj controller má docela přesah do modelu, každá třída itemu a Entity načítá svoje obrázky (Takže jsem měl problémy s vytvářením testů bez grafiky, o tom jinde). Myslím si ale, že jsem převážně oddělil třídy do správných balíků a až na výjimky každá třída dělá jednu věc pořádně.
**Flow programu:**
* Po zapnutí main třídy se inicializuje WindowView, což je třída spravující okno main menu. Tato třída také inicializuje další funkční třídy, jako GraphicsUpdateThread, MainController a nebo třeba List<Entity>, který drží seznam entit, které figurují na mapě.
* Po zmáčknutí "New Game" nebo "Last Saved Game" v menu se otevře nové okno, do kterého se mezitím načetla nová, nebo poslední uložená hra. Běh této části zaštiťuje GameSceneMaster, což je třída, která je užitečná k vybudování a propojení herní "Scény" s dalšími GUI Scénami, které fungují jako obrazovky pro inventář, menu, nebo třeba truhlu.
* (Běh herní smyčky) GraphicsThread dokola vykresluje grafiku (animační snímky hráče, entit, pozadí mapy, health bary mobů a vlevo nahoře i život, manu a peníze hráče), zatímco MainController skenuje List inputů (získaných ze scény, ve které běží hra) a v závislosti na hráčových inputech pohybuje hráčem, nebo třeba útočí. MainController také vypočítává pohyby hitboxů entit (a jejich kolize).
* Inventář, menu a otevírání beden je řešeno přes eventy v jednotlivých scénách tvořených uvnitř GameSceneMaster. ("I","E" a "ESC")
* Pokud se rozhodnu hru uložit, vytvoří se nová instance třídy FileSaver, která získá data z MainController a pomocí třídy DataStorage, která je serializovatelná uloží tato data do souboru v resources/saves.
* Pokud otevřu inventář stisknutím "I", MainController pošle List<Item> z hráčova inventáře do ChestScene (jedna ze scén, která se střídá v hlavní Stage, kde běží hra, vytvořena uvnitř GamSceneMaster), kde se tento list itemů zobrazí. Zobrazují se Background instance, které jsou uloženy uvnitř instancí itemů (Item má vlastní background, svůj sprite, který se nastaví jako pozadí tlačítka v inventáři. viz [GUI](https://gitlab.fel.cvut.cz/svobo114/java-rpg-game-pjv/-/wikis/Dokumentace/GUI-a-Grafika).
* Pokud zmáčknu "E" na otevření truhly, MainController se nejdřív podívá, jestli je v mém okolí truhla, potom jestli k ní mám klíč a pokud mám, tak mi tuto truhlu otevře (opět pošle data z truhly do příslušné scény a otevře ji v herním okně). Když zmáčknu "Mouse1" (primární tlačítko myši), charakter zaútočí na stranu, na kterou zrovna míří. MainController od hráčova modelu zjistí, s jakým poškozením útočí, pak se podívá, jestli je na daném místě kolize s hitboxem nějakého z Mobů (zranitelné entity). Pokud ano, hráč zaútočí s tím poškouzením. Pokud Mob zemře (životy<=0), hráč dostane obnos peněz.
# Jednotlivé package:
**View:**
WindowView - Spravuje Okno pro main menu a herní okno. vytvoří instance dalších potřebných tříd
GameSceneViewer - Spravuje množství různých scén, které se pak vyměňují při běhu hry a fungují jako truhla, inventář a herní menu. Tato třída také vytvoří instance controlleru a grafického vláka, které pak spustí pro běh hry, nebo je umí "naplnit" ze storage tříd získané čtením ze savefile. (neboli- tato třída zastřešuje množství funcí spojených s vytvořením herních scén a rozjetí herní smyčky.)
GraphicsupdateThread - Vlákno, které periodicky (synchronizováno <span dir="">\~</span>30Hz pomocí třídy AnimationTimer z javafx) získává snímky z entity, od hráče a vykresluje mapu/grafická primitiva (health bary, pro hráče životy a manu etc).
AnimationModel - Třída držící několik AnimatedImage, přepíná mezi animacemi, vrací se na idle inimaci etc.
AnimatedImage - Třída držící jednu animaci - s délkou, počtem snímků a jménem (a stará se o načtení oněch snímků)
**Controller:**
MainController - Třída obstarávající komunikaci mezi klíčovými třídami programu, updatování pohybu a ovládání hráče. Uvnitř běží vláko, které (opět synchronizováno <span dir="">\~</span>30Hz) vyhodnocuje kolize objektů (hitboxů), skenuje input a podle toho hýbe hráčem, útočí a nebo přepíná animace.
**Misc:** (Miscellaneous = smíšené/rozmanité) balíček tříd, které jsou důležité, ale nepatří (podle mně) přesně do žádného jiného balíku. Neznamená to, že jsou nedůležité, nebo vedlejší! Implementace a celkový návrh Hitboxu (které je v tomto balíku) zásadně ovlivňuje jakým způsobem zpracovávám pohyb, kolize a grafiku (vykresluju uvnitř hitboxu).
Hitbox - Třída držící informace o hitboxu entity. Jeho parametry a pozice. Má funkce na vyhodnocení kolize dvou hitboxů.
Coord a Velocity - jednodušší třídy držící 2D souřadnice, které se dají interpretovat jako body, nebo vektor rychlosti.
**Model:**
FileSaver - třída, která serializuje a de-serializuje třídu DataStorage do souboru(ů)
DataStorage - Třída užitá k serializaci (abych nemusel ukládat celý controller se vším všudy, uložím důležitá data (hráčův status, list entit, vybavení a inventář) do této třídy a pak ji serializuju. obrácený postup načte tuto třídu a pak použije její data k reinicializace contolleru (který drží další potřebné třídy)
Enitity -> Animation, Piture Entity & Mob - Entita je základní třída pro všechny objekty co se objeví na mapě a můžou interagovat s hráčem. Odvozené třídy AnimationEntity a PictureEntity jsou si velice podobné, ale AnimationEntity má svůj AnimationModel a může mít animované vizuály, PictureEntity vždy vrátí pouze jedena ten samý obrázek, který je pak použit pro reprezentaci. Odvozenou třídou od AnimationEntity je Mob, což je animovaná entita, která se může pohybovat (je ovládána AI vláknem), má animace a může na ni být zaútočeno. Mezi těmito třídami entit si můžu dobře vybrat, co zrovna potřbeuji pro novou entitu. Zeď a strom jsou PictureEntity, ale není důvod, proč by nemohla existovat verze stromu rozšiřující AnimationEntity, kde strom se bude kývat ve větru. (samozřejmně další velká práce by byla sehnat na všechno snímky)
Player - Třída držící info o hráči a jeho vybavení. Má (has) inventář a equipment modely. zodpovídá za přesun předmětů mezi inventářem a vybavením, ubírá a přidává hráči životy, manu a peníze.
InventoryModel & EquipmentModel - třídy držící Itemy uvnitř hráče. InventoryModel má v sobě List, který znázorňuje inventář hráče a EquipmentModel drží info o vybavených itemech
SimpleMobAI- Vlákno, které po náhodném čase řekne třídě odvozené od "Mob", aby změnila směr pohybu. (pouze jeden z mnoha možných modelů chování- Já vybral Náhodný pohyb jen pro ukázku toho, že Moby lze řídit)
Item (a dědící třídy) - Důležitá "rodina" tříd, které používám k tvoření předmětů v inventáři. Mají "Sprite", což je vlastní obrázek ve formě třídy "Background". Mají různé vlastnosti a proměnné, protože existuje rozmanité množství použití- Itemy obecně, Nositelné itemy a nebo třeba vybavitelné itemy
\ No newline at end of file