Pobierz kod Wędrowanie w świecie 2D- część 4
WĘDROWANIE W ŚWIECIE 2D (część 4)
Odsłona czwarta
Bohater trylogii wędrówki w świecie 2D w końcu znalazł w lesie karczmę, o której słyszał w części drugiej. Wie, że w karczmie jest to, co musi być...
Ale nie umie do niej wejść. Musimy mu pomóc.
Czas zacząć. Na wstępie przedstawię pewne fakty wynikające z przyjętego modelu rozwiązania organizacji świata 2D opisanego w pierwszych trzech częściach:
a) Jeśli bohater jest za drzewem lub budynkiem to ma być widoczny ale w zmienionych barwach
b) Rozpoznaje pnie drzew- umie wykryć kolizję z pniem
c) Umie chodzić tylko po ścieżkach (w tej części zrezygnuję z tej umiejętności, patrz procedura: TGracz.MoznaIsc; warunek : if(Drogi[wd,kd]>-1){or(MapaWarstwa0[w,k]=0)})
Do tego modelu należy dodać kolejne warunki:
a) W świecie 2D może (raczej musi) istnieć budynek, który osadzamy w całości (w jednym obrazie graficznym)
b) Do budynku można wejść- czyli musi być oprogramowany model wirtualnych drzwi
c) Warunek b wymaga wprowadzenia zmiany mapy w świecie 2D w obrębie aktualnego poziomu gry
d) Warunek c musi być przeprowadzony możliwie najszybciej, tak, aby nie spowalniać gry
e) Jeśli bohater jest w budynku, to nadal obowiązuje test kolizji, aby czasem go z karczmy przez ścianę nie wykopali
Tu chciałbym zwrócić uwagę na pewną trudność warunku c. Otóż, jeżeli bohater jest poza budynkiem, to wymiary budynku zajęte w mapie siatki świata 2D nie są duże w porównaniu z układem pokoi, komnat itp. jakie mogą się znaleźć w tej budowli. Powstaje problem szybkiej organizacji zmiany siatek mapy, grafiki...
Przerażający problem, jeśli się nie ma na to pomysłu. Rozwiązanie, które podam jest proste i bardzo szybkie. Ponadto łatwo ten schemat można zastosować do innego modelu warstw (w tym gigantycznych map).
Osadzamy budynek- upragnioną karczmę
Jako, że " duszki " bohaterów mają być widoczne za ścianami budynku, czyli zmieniać się na tych samych zasadach, co za drzewami przyjmę, że budynek karczmy będzie "dzieckiem" klasy Troslina. Czyli TKarczma=class(TRoslina). Do zasobów grafiki komponentu OmegaImageList należy dodać obraz budynku karczmy oraz obraz "kości" jego wnętrza.
Naszą karczmę należy gdzieś w świecie umieścić. Do unitu : swiatUnit2.pas wprowadzimy tablicę przechowującą punkt zaczepienia budynków (u nas tylko karczmy): mapaWarstwa1:array[0..19,0..19]of integer. Tę tablicę mozna traktować jako tablicę murów. Czego nie było w częściach poprzednich.
Dodatkowo ten punkt będzie wyznaczać wirtualne drzwi do karczmy. Położenie punktu w tej tablicy to 9 kolumna i 14 wiersz licząc od zera. W tych współrzędnych umieszczamy indeks odpowiadający indeksowi obrazowi naszej karczmy pobranemu z OmegaImageList1. Czyli jest to wartość 7.
Tu nie musimy się martwić, że obraz budynku karczmy będzie justowany do jej lewego boku w klatce mapy świata. Ponieważ TKraczma jet potomkiem klasy TRoslina. A w tej klasie, w procedurze rysowania obrazu jest narzucane justowanie względem środka klatki mapy. Stąd należy obraz drzwi karczmy narysować (w miarę) na środku jej ściany.
Możemy teraz w kodzie programu utworzyć nasza karczmę. Zrobimy to w procedurze tworzenia świata 2D.
Czyli procedure TForm1.TworzSwiat; Tu chciałbym zwrócić uwagę na te linijki kodu tej procedury
W przyjętym rozwiązaniu testu kolizji musimy zabronić bohaterowi wejścia do karczmy z każdej strony. Czyli uzupełnić tablicę Drogi indeksami większymi od -1 (minus jeden) Tak aby w ogólnym zarysie powstał obszar zabroniony (za wyjątkiem drzwi) odpowiadający kształtowi budynku karczmy. Powiedzmy coś takiego:
Rola tablicy Drogi omówiona jest w częściach poprzednich.
Wchodzimy do karczmy
Teraz wystarczy dojść do współrzędnych wirtualnych drzwi. Czyli w procedure TGracz.JakaKostka; należy odnotować fakt wejścia/ wyjścia z budynku. Modyfikujemy wspomnianą wyżej procedurę pprzez dodanie tych linijek:
Teraz kilka słów o jej działaniu.
Proszę zauważyć flagę logicznego stanu obecności "duszka" w budynku fWBudynku. Ta flaga będzie decydować o ukryciu obiektów nie związanych z wnętrzem karczmy. Czyli :obrazu karczmy, drzew i trawy. Jak tę flagę szybko w kodzie programu wykorzystać?
Skorzystamy z faktu, że obraz Karczmy i drzew to jedna i ta sama klasa macierzysta TRoslina żyjąca na obiektach TSprite. Aby unikać niepotrzebnych pętli, które zawsze spowalniają korzystamy z faktu, że procedury obiektów TSprite są wykonywane w zegarze aplikacji w liniach:
Więc dla klasy TRoslina wprowadzimy dodatkowa linię:
oraz
Rozwiązanie proste, skuteczne i szybkie.
Dla trawy zrobimy inaczej. Nie możemy ukryć warstwy podstawowej. Zostaje nam zmiana obrazów klatek.
Zrobią to poniższe procedury:
Nie będę tu ich przytaczać, można je prześledzić w kodzie programu. Ich działanie jest proste. Jedynie omówię w punktach pomysł jaki tu wykorzystałem:
a) Zapamiętaj siatkę dróg w buforze (warto zapamiętać niż ponownie ją odtworzyć- zysk na czasie)
b) Zbuduj nowa siatkę dróg obowiązującą w budynku
c) Ustaw w warstwie zerowej indeks -1(minus jeden) dla klatek obrazu (w poprzednich częściach wyjaśniłem, co robi takie podejście)
d) W klatkach odpowiadających podłodze budynku załaduj nowe obrazy na podstawie mapy siatki budynku. Tu: mapaKarczmaWarstwa0
e) Utwórz warstwę nr 1 na podstawie siatki mapy wnętrza budynku. Tu: mapaKarczmaWarstwa1. Uwaga tworzymy tylko tyle ile jest kostek ścian. Nie ma sensu tworzenie tyle kostek mapy dla warstwy 1 (pierwszej) ile wynosi całkowity rozmiar świata. Ten pomysł też przyczynia się do wzrostu prędkości zmiany i wyświetlania grafiki gry.
Jeżeli bohater wyjdzie z budynku to zwalniamy warstwę nr jeden i przywracamy stan poprzedni. Wszystko odbywa się bardzo szybko i w miarę prosto, bo nie ma dodatkowych indeksów zmian, flag i pętli. Warunkiem dobrej prędkości jest również trzymanie załadowanej grafiki, w OmegaImageList obowiązującej w danym poziomie gry. Pomysł można usprawnić tak, aby tablice warstw, wnętrz budynków przechowywały również indeksy obrazów a nie tylko ich klatek. Ja tu tego nie wprowadzam a to tylko ze względu na zgodność z modelem części 1,2 i 3 omawianych artykułów oraz z rozrostem map siatek (budowanie ich z klawiatury w kodzie programu mija się z celem, to musi robić nam edytor).
I to by było na tyle o piciu piwa w karczmie świata 2D