Sound Processing VII – Przewidywanie trajektorii

W tej części wprowadzimy przewidywanie ścieżki ruchu i podzielimy ruch na tury. Zapraszam.


Na czym skończyliśmy

Po ostatniej części serii odziedziczyliśmy zaimplementowany silnik fizyczny, sterowanie statkiem i prosty zoom. Do gry dorzucimy teraz przewidywanie ruchu (jak w Angry Birds) – rysowana będzie trajektoria ruchu do wskazanego punktu.

Zajmiemy się również podziałem ruchu na tury.

Przewidywanie ścieżki

Mój pomysł zamknął się w tym, aby posiadać 2 obiekty symulujące fizykę (Box2D World), mające te same tablicę z ciałami (Array<BodyDef>; statki, wyspy itd.), jeden byłby do symulacji aktualnej pozycji, drugi do przewidywania tej wskazanej (jeśli dałoby się ustawić ujemną deltę czasu, czyli cofnąć symulację po sprawdzeniu trajektorii, to wystarczyłby jeden).

W momencie wskazania punktu do którego statek ma zmierzać, ustawiam obiektom będącym w silniku do trajektorii pozycje i prędkości ciał z właściwego silnika (czyli dokładnie te same prędkości i pozycje ciał co w momencie kliknięcia) oraz ustawiam mu deltę czasu odpowiadającą czasowi jaki upłynie podczas tury symulacji (czyli jakieś 3-4 sekundy, w zależności jak będzie się wygodnie grało):

captureSimulationDot to klasa składająca się wyłącznie z wartości x, y oraz angle. Służy do zapisu kolejnych pozycji trajektorii do późniejszego rysowania.

Metoda captureSimulation() wywoływana jest w momencie kliknięcia.

Dla każdego ciała dodatkowo ustawiam flagi active, ponieważ po zmienieniu pozycji ciała (setTransform()) silnik automatycznie ustawia ją na false, co skutkuje nie sprawdzaniem kolizji dla tego ciała.

Symulacja fizyki w silniku trajektorii, pomijając ustawienie na sztywno delty i powiązanie jej z timerem, następuje dokładnie w ten sam sposób, co w zwykłym (metoda simulateAlternativeWorld() pod wieloma względami pokrywa się z simulate()), dodałem jednak do niej timer i symulację kilku następnych sekund realizuję co 200 ms, zamiast całość symulacji na jeden raz, aby nie skutkowało to krótkim dławieniem gry.

drawingDots.pngRysowanie poszczególnych punktów przewidzianego toru ruchu. Rysuję tylko pierwsze 400 punktów.

Niestety ten sposób z nieznanych mi przyczyn nie uwzględnia kolizji w trakcie ruchu,  więc trajektoria przebiega po obiektach które normalnie wchodzą w kolizję ze statkiem – do naprawienia w przyszłości.

Ruch w turach

Ruch w turach jest bardzo prosty do zrealizowania. Deklaruję timer, powiedzmy, że z wartością 3 – dopóki nie upłyną 3 sekundy, wywołuję za każdą klatką metodę simulate(),jeśli upłyną – symulacja ustaje, obiekty również zamierają w ruchu.

Klawiszem P przechodzę do następnej tury symulacji, znów ustawiając nim timer na 3.

Do tego wszystkiego dorzuciłem również nową mapę i ograniczyłem zasięg kamery do mapy – nie powiązałem nastomiast zasięgu kamery z zoomem, przez co przy krawędziach mapy, duży zoom-in nie centruje kamery na statku.

Wyniki prac wrzuciłem na YT:

Co dalej?

Próbowałem dorzucić shadery, ale muszę źle ustawiać zależności między projektami, bo Java nie jest w stanie znaleźć odpowiednich klas (z którymi IDE nie ma problemu) – również do zrobienia następnym razem.

W następnej części chciałbym dorzucić jakiś zalążek interfejsu i podłączyć modem dla pierwszej próby gry przez dźwięk.

Odnośniki:

Jak zawsze kod dostępny jest na GitHubie:

https://github.com/dbeef/soundcoding/tree/game


dsp2017-1

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s