mirror of
https://github.com/Relintai/programming_tutorials.git
synced 2025-04-23 21:53:28 +02:00
347 lines
11 KiB
Plaintext
347 lines
11 KiB
Plaintext
|
|
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...
|
|
|
|
|