Odsłona czwarta – ta która nie była przewidziana.

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:

  1. Jeśli bohater jest za drzewem lub budynkiem to ma być widoczny ale w zmienionych barwach
  2. Rozpoznaje pnie drzew- umie wykryć kolizję z pniem
  3. 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:

  1. W świecie 2D może (raczej musi) istnieć budynek, który osadzamy w całości (w jednym obrazie graficznym)
  2. Do budynku można wejść- czyli musi być oprogramowany model wirtualnych drzwi
  3. Warunek b wymaga wprowadzenia zmiany mapy w świecie 2D w obrębie aktualnego poziomu gry
  4. Warunek c musi być przeprowadzony możliwie najszybciej, tak aby nie spowalniać gry
  5. 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):

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

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

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:

  1. Zapamiętaj siatkę dróg w buforze (warto zapamiętać niż ponownie ją odtworzyć – zysk na czasie)
  2. Zbuduj nowa siatkę dróg obowiązującą w budynku
  3. Ustaw w warstwie zerowej indeks -1(minus jeden) dla klatek obrazu (w poprzednich częściach wyjaśniłem co robi takie podejście)
  4. W klatkach odpowiadających podłodze budynku załaduj nowe obrazy na podstawie mapy siatki budynku. Tu: mapaKarczmaWarstwa0
  5. 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

Pozdrawiam oksal.

Zbylitowska Góra 15.04.2006

Załączniki