Pobierz kod Uniwersalny żałnierz Świata 2D - część 1
UNIWERSALNY ŻOŁNIERZ ŚWIATA 2D- część 1
Ponownie witam wszystkich zainteresowanych tworzeniem prostych gier 2D. W tym arcie chciałbym przedstawić pomysł tworzenia (jak w temacie) uniwersalnych żołnierzy a raczej ich duszków. Powyższy rysunek przedstawia nieskomplikowaną (właściwiej by było prymitywną) aplikację budującą takich żołnierzy.
Idea pomysłu
Pomysł opiera się na takim założeniu: w zasobach grafiki mamy pliki z obrazami ludzkich korpusów, głów, broni i tarcz. Powiedzmy zorganizowanych w klatkach 32x32 piksele
Naszego żołnierza chcemy tworzyć tak jak byśmy chcieli go budować z części. Osobna klatka na korpus, głowę , broń, tarczę . Najlepiej przedstawię to tym rysunkiem:
Co nam daje takie podejście?
1. możemy utworzyć na przykład drużynę muszkieterów, którzy różnią się twarzą czyli mniejszym zasobem grafiki utworzymy setki różnych duszków (spada nam pamięć przeznaczona na zasoby)
2. łatwość przypisywania do duszka nowych broni, tarcz podczas trwania gry, konkretnie gracz zdobywa większe umiejętności; oczywiście nasz bohater może też tracić broń
3. ... w tej chwili inne zastosowania do głowy mi nie przychodzą
Wady:
1. trzeba dobrze zgrać ze sobą położenia obrazów w kolejnych
2. duszek gracza nie składa się z jednego obrazka tylko z kilku
Wada nr 2 nie jest wynikiem kłopotów programistycznych czy też zagmatwania kodu lub jego nadmiernego rozrostu. Problem tkwi gdzie indziej. Jeżeli każdą część duszka potraktujemy jako potomka klasy TSprite, to należy liczyć się z tym ze dla każdej takiej części będzie osobno wykonywana procedura Draw, Move, Dead, Collision. Proszę zobaczyć na ciało procedury "zegara" gry.
Tu chciałbym jeszcze raz podkreślić że w programowaniu obiektowym dla nie ma sensu wykonywać pętli po każdym duszku. To tylko spowalnia grę. W OMEDZE rysowaniem, przesuwaniem, uśmiercaniem i kolizjami zajmuje się TOmegaSprite (podobnie jak i w DelphiX).
Wracam do tematu...Czyli jeden żołnierz będzie traktowany tak jak byśmy mieli do czynienia z czterema.
Ale jest na to rada.
Model uniwersalnego żołnierza...
będzie się składać:
" korpus to klasa TSprite
" głowa, bron i tarcza to tylko rysunki
Czyli korpus będzie reagował na Move, Draw, Dead, Collision pozostałe części są tylko rysunkami które są wyświetlane w procedurze Draw korpusu poleceniem:
Jedynie musimy zadecydować jaka część będzie pierwsza rysowana. Otóż jeżeli widzimy kogoś idącego na Wschód to jego lewe ramie jest nie widoczne. Przyjmując, że nasz uniwersalny żołnierz jest praworęczny, to tarcze będzie nieść na lewym ramieniu...Inaczej mówiąc o kolejności wyświetlania części naszego duszka będzie decydować jego kierunek ruchu.
Poniżej przedstawiam procedurę
Procedury rysowania w zależności od kierunku ruchu są umieszczone w procedure tZolnierz.Draw; Nie będę szczegółowo analizował tych procedur, pozostawiam to tobie czytelniku. Jedynie chciałbym zwrócić uwagę na tego typu warunek
Ten warunek da nam łatwość oprogramowania zmian postaci. Na przykład gracz traci tarczę lub ją zmienia ale o tym decyduje ta zmienna: fIdKlatkaTarcza (oczywiście dla tarczy)
Zapis modelu żołnierza
Odbywa się w pliku tekstowym . W dolnym prawym rogu aplikacji są umieszczone odpowiednie przyciski oraz lista utworzonych modeli. Można kliknięciem myszki takie modele wybierać. Dane w pliku są zapisywane wierszami (każdy wiersz to osobny model) według schematu:
{indeks korpusu}spacja{indeks głowy}spacja{indeks broni}spacja{indeks tarczy}
Indeksy obrazów zasobów grafiki zapisanych w OmegaImageList nie przechowuję ponieważ jest to poglądowa aplikacja. W rzeczywistym rozwiązaniu należało by przechowywać te indeksy lub lepiej nazwy zasobu. Będziemy mieć większą elastyczność przy dodawaniu nowych obrazów. Pewnie ktoś może zarzucić temu rozwiązaniu, ze polecenie Find będzie działać wolniej. Tak to prawda. Ale należy je użyć tylko raz w momencie tworzenia całej postaci po odczycie danych z pliku i zapamiętać indeks takiego zasoby.
A jak zapamiętać? Robić jakieś liczniki? Nie to tylko pogmatwa sprawę
Rozwiązanie jest proste. Wystarczy odczytać co jest zapisane w
OmegaImageList1.ImageList.Find('bron').ID
OMEGA jest fajna...na jeziorze też szybko śmiga
No to tyle w części pierwszej. W części drugiej planuję przedstawić model ruchu, kolizji i akcji zabierania broni Ruch i kolizja będzie oparta na modelu ruchu borostwora z Wędrówek w świecie 2D