Jak by tu zacząć… najlepiej to pociągnąć temat już rozpoczęty. Z praktycznego punktu widzenia, to dokończyć model świata 2D przedstawiony w temacie: Izomeria w świecie prostokątnym. Powiedzmy, że chcemy nasz świat ożywić. Zacznijmy od ruchu postaci bohatera gry, sterowanego z klawiatury. Poniżej bohater na tle murów

Niby sprawa prosta. Algorytm wyświetlenia li tylko grafiki można opisać tak:

-wyświetl grunt
-wyświetl zamek
-wyświetl bohatera

Ogólnie tak to powinno przebiegać. Można powiedzieć: programowanie to rzecz prosta, prostsza od piractwa płyty, którą trzeba ..coś tam, coś tam lub utworzenia strony www (czego ja nie umiem i nie chcę umieć). Ale niestety tak nie jest. Bohater świata 2D ma wiele problemów natury istnienia w tymże świecie. Chociażby poniższa sekwencja obrazków wprowadzi w temat.

Jakie to problemy? Jest ich sporo. Wymienię tylko kilka:
-bohater/duszek musi być wyświetlony na tle budowli
-bohater/duszek musi być wyświetlony poza budowlą
– bohater/duszek musi umieć żyć pełnia swojego życia w świecie 2D( chodzić, biegać, polować, zabijać itp.)
– bohater/duszek musi umieć schować się za drzewem lub za nim przejść

A to nie wszystko…a gdzie dźwięk, zdarzenia losowe, przeciwnik, sztuczna inteligencja, w miarę duży świat itp. Jedna osoba szybko gry nie napisze. Ale może pokonać w/w trudności używając Pascala (czytaj Delhi) i Omegi. I gdybym był zadufanym pascalowcem powiedziałbym, że w C się tego nie da zrobić. A zwłaszcza dla gigantycznych światów 2D przy założeniu, że chcę utrzymać przyzwoity FPS. Proszę mi wybaczyć tą dygresję, ale wkurzają mnie wypowiedzi hołubiące li tylko wybrany język. Mam na myśli C. Wystarczy zobaczyć kilka omawianych projektów na http://www.gamedev.pl/ I co się okazuje Postacie skaczą, co klatkę świata, ma się ogólne wrażenie, że są to przeróbki kodów dostępnych w książkach ( tu zaznaczam mam na myśli 2D, o 3D się nie wypowiadam, bo mam braki w praktycznej wiedzy). Fakt, jest kilkanaście autorskich projektów… ale to perełki.

Inaczej mówiąc to, co wyżej powiedziałem to nawiązuje do jakiejś dziwnej wojny języków. W pisaniu programów nie o to chodzi. Każdy pomysł można zakodować w dowolnym języku. Wszystko zależy od opanowania tego języka….A wiec do sedna tematu czas przystąpić.

Cała treść tego artykułu bazuje na wcześniejszych pomysłach opisanych w Wędrówkach…

1. Jak pokonać podstawowe trudności życia w świecie 2D przedstawione na poprzedniej ilustracji?

Problem wyświetlania obrazu duszka na tle budowli lub za nią, ewentualnie za rośliną lub artefaktem wiąże się za poprawną kolejnością wyświetlania grafik. Jeżeli coś spapramy to będziemy mieć tak jak poniżej ( w demku można to sprawdzić- jest to efekt zamierzony). Ta.. pierwotniak chodzi po dachu świątyni.

Dlaczego tak się stało?

Oczywiście zakładamy, że nasz bohater nie posiada takiej umiejętności. Na dachu znalazł się przypadkiem.. Jak do tego doszło? Odpowiedź jest prosta: duszek bohatera został wyświetlony później niż obraz kościoła. Jeżeli wyświetlimy go wcześniej to budynek go zakryje. Zarówno jak stanie za budynkiem lub przed budynkiem. To nie będzie dobre rozwiązanie. Jak temu zaradzić? 
Już odpowiadam: na poziomie edytora światów.

Proszę zanalizować poniższy rysunek

Duszki w pozycji : B5 i C4 wlazły na dach. Zaś duszki C3, D3, E2, F2 oraz F3 są wyświetlone prawidłowo. I znów można zadać pytanie: dlaczego tak się stało? Przecież mechanizm wyświetlania duszka jest taki sam. Odpowiedź jest jedna : musimy opanować głębie. Tak ,tak do tej pory poniżej 10 000 metrów „zeszło” tylko dwóch ludzi- pod koniec lat pięćdziesiątych, a na orbitę wyleciało prawie czterystu. I to porównanie jest skalą problemu, który nas czeka. Nic tylko siąść i płakać, ewentualnie przesiąść się na C i też płakać… Ale wystarczy tylko zauważyć jedno- to o czym pisałem w Wędrówkach w świecie 2D – głębia może być stowarzyszona z wierszem. Im wyższy numer wiersza tym wcześniej klatka jest wyświetlana. Czyli jeżeli byśmy osadzili kościół tak, aby środek jego obrazu był w kaflu D4 i zarazem głębia kościoła byłaby pobrana z numeru wiersza tego kafla to wszystko, co byłoby na pozycji poniżej wiersza czwartego będzie wyświetlane wcześniej niż obraz kościoła, a to, co powyżej później. Najłatwiej jest to rozwiązać przez wprowadzenie zakazu ruchu- duszek nie może wejść na dach kościoła.
Czyli obraz drogi powinien być tak uzupełniony, aby, na B5 i C4 nie można było postawić duszka- co na poniższym rysunku nie jest uwzględnione- można więc chodzić po dachu

 

No tak, rysunki przedstawiają wynik zapisu mapy świata gry. Oczywiście organizacja tego zapisu zależy od edytora. Odczyt do silnika gry. Sam odczyt stwarza wiele możliwości rozwiązań. Ja zaproponuję moje, które nie należy traktować jako to jedyne.

2. Głębia bohatera (to nie temat dla humanistów)

Problem należy rozpatrzyć pod kontem kolejności wyświetlania grafiki. Problem jest prosty do rozwiązania gdyby nie było możliwości chodzenia za przeszkodą ( szerzej opisałem to w Wędrówkach..) Jeżeli chcemy chodzić za drzewem lub budynkiem to musimy znać kolumnę i wiersz przebywania duszka w świecie 2D i na tej podstawie wyliczyć głębie. Można też ją odczytać, co będzie rozwiązaniem mniej czasochłonnym. Głębia jest znana dla każdego kafla warstwy- patrz kod tworzenia warstw. Jeżeli chodzi o duszka to, obsługuje to ta oto procedura

Jak widać określam dwa razy położenie duszka. FKolumna i fWiersz to położenie obowiązujące w całej mapie- świecie 2D, a k i w to poleżenie warstwach widocznych na ekranie. Może to dziwić , ale tak jest zorganizowany mój model gigantycznego świata. Odczytaną wartość

zwiększam o jeden, a to tylko dla tego, aby można było stanąć na tle budynku lub drzewa

Wspomniana procedura musi być ciągle wywoływana w czasie ruchu duszka czy to sterowanego z klawiatury czy też automatycznie

Dla duszka poruszanego z klawiatury , czyli bohatera którym aktualnie gramy wystarczy nam znajomość pozycji w warstwach widocznych. Automat musi znać jedną i drugą pozycję. Na razie nie robię zabezpieczenia przed wyliczeniem kw wykraczającym poza tablicę SwiatProstokatnyWarstwy bo w omawianym przykładzie nie występuje żaden automatyczny duszek. Może będzie to w następnej części…

3. Sterowanie bohaterem i animacja ruchu

W świecie izometrycznym możemy poruszać się w kierunkach od 0 do 360 stopni. Należy zadbać o odpowiedni obrót duszka. Jako że obraz duszka wyświetlany jest w kolejnych klatkach animacji ruchu dla danego kierunku zdecydowałem się na 8 kierunków ruchu

W załączonym kodzie skręcanie odbywa się przy pomocy klawiszy kursora strzałka w lewo lub prawo. Naprzód to strzałka w górę, do tyłu to strzałka w dół. Oprogramowanie ruchu nie jest rudne należy tylko odpowiednio przerzucać indeksy klatek do obranego kierunku ruchu

Poniżej fragment kodu z unit pierwotniak;

Jest to tablica która przechowuje indeks początkowy i końcowy klatki animacji dla danego stanu życiowej aktywności duszka. Przykładowo poniższe wartości liczbowe

odpowiadają:
(16,23) – klatki ruchu idź na północ od numeru 16,17,18…23
(24,31) – klatki ruchu idź na północny wschód od numeru 24,25,…31
(32,39) – klatki ruchu idź na wschód od numeru 32,32,…39

I tak dalej. W tej tablicy są przechowywane indeksy biegu, mówienia itp. Może jedynie zdziwić, to że

Dane- indeksy ponownie maleją. Otóż duszek złożony jest z dwóch plików graficznych. Ich nazwy odpowiadają nazwom z zasobów oil i są zapisane do tablicy

Procedura procedure tPierwotny.Akcja; obsługuje zmianę obrazów zachowań. Zawiera ona taka procedurę ZmienObraz(tabGrafikiPierwotny[1]); to tu następuje zmiana indeksu ładowanego obrazu z zasobów OmegaImageList zaś same klatki animacji zmieniam tu:

a to metoda ojca

Teraz jedynie należy w zegarze gry oprogramować reakcję duszka bohatera na wciśnięty klawisz. Są to te linie kodu

Gdyby to był automat należałoby wykorzystać procedury

Dokładnie na tych samych zasadach co opisałem w ruchu borostwora w Wędrówkach…

Klawiszologia zachowań omawianego duszka:
– klawisze strzałek- idź
– Lewy Shift plus strzałka w górę – bieg
– klawisz M (wciśnięty)- mów
– klawisz O (wciśnięty)- okrzyk

4. Kolizja ruchu

Polega na stwierdzeniu czy można w danej klatce postawić duszka. W tym przykładzie stwierdzenie wystąpienia 1 (jedynki) lub końca świata oznacza zakaz ruchu

Całość kodu znajduje się w function tPierwotny.Kolizja(aX,aY:single):boolean; należy jedynie ta funkcje uruchamiać w momencie wciskania klawiszy ruchu i stwierdzić czy można postawić duszka w nowej pozycji. Jak nie to wyskakujemy z akcji ruchu

I to by było na tyle

Pozdrawiam Adam Lasko (oksal) 10. XI. 2007 Zbylitowska Góra

PS
Do prawidłowego działania przykładu wymagane są te pliki

swiat_512x384.mue2D
teren_rosliny.oil
swiatynie.oil
zamki.oil
pierwotny001.oil
D3DX81AB.DLL
MPPSDK.DLL

Autor: oksal

Załączniki

  • zip izo2
    Rozmiar pliku: 4 MB