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. Jeżeli czytelniku chcesz się wgłębić w rozbudowę AI to polecam projekt Tostera (link do projektu podaję z unit1.pl: https://unit1.pl/forum/viewtopic.php?t=50 )

Klasa borostwora znajduje się w pliku UnitStwor000.pas;

ZAŁOŻENIA

  1. W zależności od kierunku ruchu odpowiednio dobierana jest animacja klatek
  2. Duszek borostwora zmienia kolor w cieniu przeszkody na tych samych zasadach co duszek bohatera
  3. Wykrywa kolizje z pniem drzewa
  4. Losowo dobiera kierunek ruchu
  5. Wchodzi do karczmy
  6. 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:

  1. Sprawdź kolizję z innymi borostworami i duszkiem gracza
  2. Rysuj duszka borostwora według tych samych procedur co bohatera ( omówiłem w poprzednich częściach)
  3. 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) 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ę

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

Jest to najciekawsza procedura. Jej powstanie zawdzięczam Iskarowi. Krytyka robi swoje. Tak więc Panowie nie psioczyć na forum…Pomysł na jaki wpadłem jest tak prosty( a to co proste jest genialne, młotek trudno zepsuć i łatwo jest naprawić, bo to prosta , genialna konstrukcja).

Ale do rzeczy…

Przytoczę nagłówek procedury kolizji obiektu TSprite komponentu Omegi

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 BOROSTWORA

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.

Pozdrawiam oksal

Zbylitowska Góra 15.05.2006

Autor: oksal

Załączniki