Pobierz kod Wędrowanie w świecie 2D- część 5
WĘDROWANIE W ŚWIECIE 2D (część 5)
BOHATER SPOTYKA DUŻO DUŻYCH BOROSTWORÓW...
i jest to duży problem, nie ze względu na charakter spotkania (choć bohater świata 2D ma inne zdanie) ale na sposób oprogramowania natury BOROSTAWORA. Taki stwór musi się jakoś zachowywać a jego duszek powinien być oprogramowany według tych samych zasad, co duszek bohatera.
Ten artykuł porusza problem duszka stwora. Jego AI zostawiam na poziomie losowego doboru kierunku ruchu.Klasa borostwora znajduje się w pliku UnitStwor000.pas;
ZAŁOŻENIA
a) W zależności od kierunku ruchu odpowiednio dobierana jest animacja klatek
b) Duszek borostwora zmienia kolor w cieniu przeszkody na tych samych zasadach co duszek bohatera
c) Wykrywa kolizje z pniem drzewa
d) Losowo dobiera kierunek ruchu
e) Wchodzi do karczmy
f) Nie ucieka poza obszar dostępnego świta
Jak widać warunki b, c, e są wspólne z klasą duszka bohatera. Ten fakt prowadzi do wniosku, że należy utworzyć wspólna klasą - rodzica dla bohatera i borostwora i z tej klasy tworzyć "dzieci" tych duszków. Pisząc część pierwszą "Wędrówek w 2D" nie przewidywałem występowania borostworów, stąd klasę duszka borostwora utworzyłem bezpośrednio na TSprite. Choć można było wybrać i TSimpleAnimSprite, która to posiada mechanizm animacji klatek. W TSprite też da się to zrobić i to w trzech linijkach:
Dodatkowo osoby zainteresowane maja odpowiedź jak oprogramować duszka bohatera, aby się zmieniały jego klatki ruchu.
Tyle słowa wstępnego. Przystępujemy do pracy...
ALGORYTM DUSZKA BOROSTWORA...
Zegar gry wywołuje w takiej kolejności procedury związane z obsługa klasy bazowej duszka borostwora- TSprite
Co prowadzi do takiego postępowania:
a) Sprawdź kolizję z innymi borostworami i duszkiem gracza
b) Rysuj duszka borostwora według tych samych procedur co bohatera ( omówiłem w poprzednich częściach)
c) Podejmij akcję związaną ze zmianą położenia
Krok a nie wykrywa kolizji z pniami tylko z duszkami obiektów żywych a to tylko dla tego, że jak przyjdzie do szukania drogi do wskazanego celu to na takim teście kolizji nic nie znajdziemy. Drogi się szuka z siatek mapy np algorytm Dijkstry
Krok b jest przeniesiony z klasy TGracz
Krok c to przebudowana procedura Move(const MoveCount:single) oraz MoznaIsc(MoveCount). Ich zadanie polega na symulowaniu decyzji związanych z ruchem borostwora. W przypadku gracza było to banalne wystarczyło odczytać jaki klawisz wciśnięto na klawiaturze. Tu na podstawie mapy wykonujemy ruch
BOROSTWÓR ZMIENIA POZYCJĘ
Chodzi o ten fragment kodu programu
Jest to przebudowana procedur z klasy TGracz. Idea ta sama co w analogicznej funkcji ruchu Gracz (wyjaśnienie w poprzednich częściach). Zmiana położenia odbywa się w funkcjach kierunku (osiem kierunków zgodnie z Różą Wiatrów)
kierunekN (2*Value); kierunekNE (2*Value); i tak dalej. Zastępuje to wciskanie klawiszy ruchu. Tu podkreślam, że te funkcje wyznaczają zmianę współrzędnych według tych linijek
Linijki te nie reagują na przesuwanie wykonane przez Gracza. Duszek Gracza zawsze jest we współrzędnych środka ekranu. To świat przesuwa się względem Gracza. I my ten fakt musimy uwzględnić. A wykonujemy to
w tym miejscu kodu
Dodatkowo należy omówić procedurę
Odbicie;
Procedura ta, wyznacza wolne pola z tablicy Drogi przy kolizji z pniem. Z tych pól tworzona jest tablica dynamiczna i z niej losowo je wybierane takie pole poczym zostaje ona zwolniona. Idee działania przedstawię na jednej z wewnętrznych funkcji tej procedury.
Powiedzmy, że uderzenie w pień drzewa (matematycznie w pole siatek dróg) następuje z południa. Działanie funkcji nie będę opisywać. To można prześledzić w poniższych linijkach:
Pomysł jaki tu wykorzystałem zobrazuje tym rysunkiem:
Polu z iksem, jest zajęte przez pień drzewa, BOROSTWÓR nadchodzi z kierunku południowego (strzałka czerwona). Możliwe pola po odbiciu wskazują strzałki niebieski. Teraz wystarczy wyznaczyć wiersze i kolumny takich pól, sprawdzić czy są dostępne do wykonania ruchu, utworzyć z nich tablicę i wylosować takie pole. Proste podejście, bo szybciej jest dostać się do indeksów niż wyznaczyć to z funkcji trygonometrycznych. Szybkie wyliczenie indeksów odbywa się w pętli poprzez dodani lub odjęcie liczby 1 (jeden) względem pola przeszkody. Czy dodawać lub odejmować to najłatwiej jest to określić stałymi wartościami przechowywanym w tablicy. Podam fragment z kodu
Dla ułatwienia ułożyłem ją tak jak na powyższym rysunku. Wyznaczenie możliwych pól po odbici dla pozostałych kierunków są analogiczne.
KOLIZJE Z INNYMI DUSZKAMI
Przytoczę nagłówek procedury kolizji obiektu TSprite komponentu Omegi
onCollision(const Sprite:Tsprite;const colX,colY:integer);
Procedura ta podaje bardzo ważną informację. A mianowicie zwraca współrzędne zderzenia duszka z innym duszkiem. Wynik to colX, colY. Jak ktoś uważa na lekcjach fizyki lub świeci lustrem ludziom po oczach, to wie że kąt padania i odbicia promienia światła jest taki sam i leży na jednej płaszczyźnie.
Świat 2D z natury jest płaski- jeden warunek mamy już spełniony. Kąty obliczymy w prosty sposób (proszę dosłownie nie utożsamiać naszego kąta kierunku odbicia z prawidłowym rachunkiem wynikającym z tego prawa), gdy tylko coś zauważymy.
ALGORYTM
" podziel klatkę duszka na 4 części (dwie kolumny i dwa wiersze)
" przypisz kierunki z Róży Wiatrów tym częściom według tej kolejności: NE, NW, SE, SW (proszę zauważyć ze w cale nie podałem w prawidłowej kolejności to znaczy NW,NE, SW, SE, zbieg ten należy rozumieć tak: jeżeli uderzenie nastąpiło z kierunku NW to odbicie będzie w kierunku NE)
" sprawdź w której części- polu leżą współrzędne kolizji
" na podstawie indeksu pola określ kierunek odbicia
Poglądowy rysunek:
Oczywiście nic nie stoi na przeszkodzi aby zwiększyć podział na 8 kierunków (czyli 9 pól, środkowe jakoś w tedy należy potraktować inaczej lub przypisać mu już raz przypisany kierunek)
ZABEZPIECZEINIE PRZED UCIECZKĄ BOROSTWORA Z MAPY ŚWIATA
Podam najprostszy pomysł dla tego modelu organizacji świata 2D. Proszę zauważyć, że klatki mapy to też duszki. Znamy więc współrzędne ich rogów Wystarczy więc sprawdzać czy współrzędne X i Y borostwora nie wystają poza skrajne rogi mapy świata...Jeżeli wystają w boku zachodnim to zmień kierunek na zachodni itd. A są to te linie kodu:
ANIMACJA KLATEK BOROSTWORAb>
Pod uwagę wezmę jedną z ośmiu funkcji wyznaczających kierunek ruchu. Kierunek ruchu decyduje jakie klatki maja być brane pod uwagę. Jeżeli popatrzymy na plik zasobu grafiki
To zauważymy, że aby iść na wschód to trzeba dostać się do pierwszej klatki z ostatniego wiersza Czyli 9 licząc od zera.
Jak to zrobić?
Nie jest to trudne, trzeba wprowadzić pewien skok w takiej tablicy klatek tu jest to liczba 9 (aby iść na południe to była by to liczba 3) A ze potrzebujemy 3 klatek ruchu w danym kierunku (klatka 0,1,2) to odpowiednio zwiększając taki indeks plus skok wynikający z obranego kierunku mamy gotową animację po klatkach.Wynik wstawiamy do ImageIndex
Stosując odpowiednie ofsety klatek możemy uzyskać różne animacje np. animacja strzału, skoku itp. Ważne, aby takie klatki były zapisane w jednym obrazie. O prędkości animacji decyduje ten warunek zwiększania licznika:
Wartość dVA ustalona jest w momencie tworzenia duszka, Value jest pobierana z zegara aplikacji gry. Podczas wykonywania kodu gry jest ona zerowana, gdy występuje zderzenie z innym duszkiem. Unika się efektu migotania wynikającego z nakładania zmieniających się klatek tych obiektów. Może również posłużyć do przyspieszani a lub opóźniania, animacji w zależności od sytuacji na przykład bieg.
Nasze dzikie BOROSTWORY tworzymy tak
I będzie ich w najlepszym przypadku 100 sztuk.
Nasz BOROSTWÓR umie wchodzić do karczmy. Proszę sprawdzić. Wystarczy wejść do karczmy i troszkę w niej posiedzieć a na pewno ktoś do nas przyjdzie. I cieszmy się, że nie będzie chciał na piwo.