Egyéb feladatok. Ezeket már nem fejtettem ki teljesen, csak "guideline"-okat, és ötleteket írok róluk. ============================== Asset DB ============================== Egy olyan osztály, amely képes tárolni, és elérhetővé tenni (Singleton), a betöltött pl Textúrákat, és egyéb több helyen szükséges resource-okat. Lehet pl map-okat rakni bele, string kulccsal, de pl lehet vectort, ami structokat tárol, amikbe string név és resource típus van (lehget pl template, de akár minden típoushoz lehet kézzel is cisnálni.), de lehet például enum, vagy konstans int kulcsokat is használni, stringek helyett. A program elején töltsétek be a szükséges dolgokat, és innen legyenek elérhetőek. (Nyilván közbe is lehet betöltögetni, de nem lessz rá szükség ilyen egyszerű programoknál.) ============================== Animated Sprite ============================== Animált Sprite. Azaz egy olyan Sprite osztály, amelynek van update(float delta) metódusa, és vagy van egy Sprite vectorja, amiben Sprite-okat lehet eltárolni, vagy a megadott textúrát tudja x és y darabra osztva kirajzolni. (Nyilván nem kell annyi textúrát létrehozni, elég csak a clip_rect-et állítani a megfelelő időben.) Kell neki még egy változó, amivel az animáció sebességét lehet állítani. És minden (animáció sebesség) időnként képkockát fog váltani. A kipróbálásához pl lehet OpenGameArt-on "sprite sheet"-eket keresni. ============================== Tile Map ============================== Egy olyan osztály, amelyben vagy egy 2d-s int tömb (vagy természetesen 1ds, vagy akár lehet régiókra is osztani, azaz sok 2ds-tömb), és van egy tile_size változója (Lehet x, y külön is). Illetve van benne egy sprite tömb, (De lehet akár map is), és képes kirajzolni magát, méghozzá úgy, hogy tile_size méretű rácson a 2ds int tömb alapján a rácsra a sprite-okat ráhelyezi. A Sprite-okat nem muszály clip-eltetni vele tile_size méretre. Valószínűleg egyszerűbben érthető, ha rákerestek keresőben a "tile map" szóra, és/vagy ránéztek pl a Tiled-re (https://www.mapeditor.org/). A kipróbálásához pl lehet OpenGameArt-on "tile set"-eket keresni. ============================== Bitmap Font ============================== Megj.: Majdnem teljesen ugyan az, mint a TileMap! Ha azt megcsináltátok, csak alakítsátok át ezzé. Ez egy olyan osztály, amely szöveg kiírását fogja tudni elvégezni, az ablakonkra. (Lehet, hogy meglepő, de szövegek megfelelő kirajzolása meglepően nehéz feladat! Sőt! Valójában szinte biztos, hogy ehhez hasonló módszert alkalmaz szinte minden program, ugyanis betűk kirajzolgatása a font fájlokból idő és processzor igényes, és ezzel a módszerrel egyszerűen optimalizálható. Amúgy, az dsl-nek van egy sdl_ttf nevű kiegészítő könyvtára, az is ugyan ezt csinálja a háttérben!.) Nyilván, a legeszerűbb mód a szövegek kiírására, ha ugyan azt csináljuk, mint a TileMapnál, csak kicsit erre a célra átalakítva. ------- Lehet úgy csinálni, hogy van egy vektorunk, amiben Sprite*-okat tudunk tárolni. Akár be is allokáltathatunk 256-os méretre. És egyesével beállítgatjuk a megfelelő helyre a megfelelő Sprite-ot. (A char típus a háttérben unsigned 8 bites int! Azaz simán lehet vele indexelni! (Ha a fordító esetleg nyavajogna, akkor triviálisan átcastolható pl int-é!)) Ennek a megoldásnak előnye, hogy a betűk lehetnek más méretűek, illetve, hogy kevesebb átlátszó pixelt kell majd rajzoltatni. Viszont hátránya, hogy sok kód létrehozni egy példányt belőle. ------- Másik megoldás, hogy azt mondjuk, hogy fix méretű betűtípust használunk (Monospace font). Ekkor csak a betűk méreteit kell megadni, illetve, egy stringet, amely tartalmazza a karakteketet, a megfelelő sorrendben, és máris létrehozható egy példány. ------- Ami függvények mindenképp legyenek: get_width(String s) -> Megmondja, hogy mekkora lesz a megadott szöveh szélessége get_height(String s) -> Megmondja, hogy mekkora lesz a megadott szöveh magassága draw(String s, int x, int y) -> kiírja a szöveget a megadott helyre draw_centered(String s, int x, int y) -> kiírja a szöveget a megadott helyre, középre igazítottan. Valószínűleg egyszerűbb, ha magatok összedobtok egy egyszerű teszt képet, de rá is lehet keresni "bitmap font" okra az interneten, nagyon sok van belőlük. ============================== Widget készlet ============================== Írjunk egy egyszerű Widget készletet. Megj.: Ha már van használható BitmapFont osztályotok, midnenképp használjátok fel itt, ha nincs akkor sincs probléma, akkor viszont minden szöveget kézzel kell megcisnálni, és betölteni képekként. Sokféleképpen lehet widget készletet készíteni. Itt egy megoldást fogok ismertetni, a lehetőségek közül. ( Egyéb típusú implementációk közül érdemes utánanézni az ú.n. Immedaite Mode Gui-knak. (pl https://github.com/ocornut/imgui - A Unity is ezt használja a régi GUI rendszereként, és az editor scriptelésére.) Pontos magyarázat (angol): https://www.youtube.com/watch?v=Z1qyvQsjK5Y Ezek implementálhatók osztályok felhasználása nélkül is, és amúgy nagyon jól kezelhetőek. Ha valakinek ez a stílus jobban tetszik, akkor ezt csinálja! Megj.: Az alul ismertetett osztályok ugyanúgy felhasználhatók ennek az implementálására is, csak így akkor statikus függvényekkel lesznek tele. ) ---------- A mi widget készletünk úgy fog kinézni, hogy van egy ős Widget osztály, amely tartalmaz egy Widget* vektort - Ezeket gyerekeknek / child fogom hívni. Minden másik Widget ebből származik le. Az alap ötlet az, hogy elég a legfelső widgetet eltárolni, és annak adogatni az eventeket, annak hívogathi a frissítés metódusát, etc, és akkor az meghívja az összes gyerekének az ugyanilyan efüggvényeit, etc... Lesznek olyan Widgetek is, amelyek kezelik a gyekrekeik méretét. Így nagyon egyszerűen készíthetőek meglepően bonyolult guik is, alig néhány kis widget osztály elkészítésével. Azaz: Pl egy egyszerű középen levő játékmenü felépítése: Container (Ezt a külső Scene osztály hozza létre, és méretezgeti folyton az ablakmérethez, ha az változik) CenteredAspectContainer PanelContainer VBoxContainer LabelButton LabelButton LabelButton LabelButton Pl a notepad program elékszítése, egy felső menüsávval (Popup menük nélkül): Container (Ezt a külső Scene osztály hozza létre, és méretezgeti folyton az ablakmérethez, ha az változik) VBoxContainer PanelContainer - Felső menüsáv grafikás háttere HBoxContainer LabelButton - pl mentés LabelButton - pl kilépés gomb etc LabelButton LabelButton TextEdit - Ez nem lesz benne az alab WIdget készletbe Még egy fontosabb dolog, hosszú távon érdemes megoldani, hogy ha egy Widget felhasznál egy eventet, akkor már azt az eventet ne dolgozzuk fel tovább, mert azzal csak cpu időt vesztegetünk. Sőt, később arra is hasznos lesz, ha ezt beimplementáljátok, hogy ha a Widget készlet nem használja fel az eventet, csak akkor kapják meg a program más részei. Ezt nyilván sokféleképp meg lehet oldani, egyik lehetséges mőd, ha a Widgetek handle_event() virtuális függvényei ha true-t adnak vissza, akkor felhasználták az eventet, és nem folytatódik tovább a gyereket végigellenőrzése, sőt pl a Scene maga is tudni fogja, hogy az event fel lett használva. Megj.: Erre a típusú widget készletre nagyon szemléletes példa a Godot nevű játékmotorben található. (A Widget-et itt Control-nak hívják!) ---------- Widget ------ Legyen benne egy Widget* -at tartalmazó vektor. Legyen benne virtuális: update(float delta), bool handle_event(SDL_Event/írhattok sajátot), render(), és resize() függvények. Hasonlít a Button-ra a 23_sdl_button.txt-ből. Tárolja a saját méretét. Alapból nem rajzol ki semmit. Container : Widget ------------------ Olyan Widget, amely a saját méretéhez állítja a gyerekei méretét. CenteredAspectContainer : Container ----------------------------------- Olyan Widget, amely a saját méretéhez állítja a gyerekei méretét, de úgy, hogy középre igazítja őket, és megadható, hogy hány százalék-al legyenek kisebbek az x-en, és y tengelyen. PanelContainer : Container -------------------------- Egy sima containre, annyi különbséggel, hogy rajzol egy hátteret a render() metódusában. HBoxContainer : Container ------------------------- A gyerekeit egymás mellé rendezi vízszintesen. Azaz: |-----------| |W1|W2|W3|W4| |-----------| VBoxContainer : Container ------------------------- Ugyan az, mint a HBoxContainer, csak függőlegesen rendezi egymás mellé a gyerekeit. Label : Widget -------------- Egy szöveget ír ki. Megcisnálhatjátok, hogy ha a szöveg túl lóg rajta, akkor azokat a karaktereket már ne írja ki. Button : Widget --------------- Gomb widget. Gyakorlatilag ugyan az, mint a 23_sdl_widgetes példa gombja. LabelButton : Button -------------------- Egy gomb, amyl képes szöveget kiíratni magára. (Ekvivalens azzal, mintha lenne egy rejtett, nem kitörölhető label gyereke.) ImageButton : Button -------------------- Egy gomb, amely re rakható egy kép. Image : Widget -------------- Egy képet kirajzoló Widget. Megj.: A teljesen kiforrot ilyen felépítésű widget készletekben, általában van a minimum méretet meghatározó változó, és olyan is, amely megengedi a widget vízszintes/horizontális nyújtását. Ilyenkor pl a VBoxContainer az mindent a minimum méretére méretez be, és utána kinyújtja a maradék helyre az összes egyéb widgetet, amelynél ez be van kapcsolva. Így pl elég egyszerű status bar-okat csinálni. Számunkra ez nem olyan fontos, de ha valaki érdekes feladatnak látja, nyugodtan csinálja meg. ============================== Notepad ============================== Írj egy nagyon egyszerű Notepad szerű programot, a widget készleted felhasználásával. Az se probléma, ha nem lehet szerkeszteni a szöveget. ============================== Táblázatkezelő ============================== Írj egy nagyon egyszerű excel szerű táblázatkezelő programot, a widget készleted felhasználásával. ============================== Pong klón ============================== Írj egy Pong klónt. ============================== Breakout klón ============================== Írj egy Breakout klónt. A Tile Map osztállyal egyszerűen megoldható. ============================== Snake játék ============================== Írj egy snake klónt. A Tile Map osztállyal is egyszerűen megoldható. ============================== Monopolys programhoz gui ============================== Írj az előzőleg kifejleszett Monopolys szimulációhoz egy felhasználói felületet. ============================== Raycaster ============================== Implementálj egy Raycaster-t. Pl.: https://www.youtube.com/watch?v=gYRrGTC7GtA https://www.youtube.com/watch?v=PC1RaETIx3Y https://www.youtube.com/watch?v=eOCQfxRQ2pY etc...