Szybka, dokładna kolizja 2D

17

Pracuję nad strzelanką 2d topdown, a teraz muszę wyjść poza mój podstawowy system kolizji z prostokątami.

Mam duże poziomy z wieloma różnymi duszkami, z których wszystkie mają różne kształty i rozmiary. Tekstury dla duszków to kwadratowe pliki png z przezroczystym tłem, więc potrzebuję też sposobu, aby zderzyć się tylko wtedy, gdy gracz wejdzie w kolorową część tekstury, a nie przezroczyste tło.

Planuję poradzić sobie z kolizją w następujący sposób:

  1. Sprawdź, czy jakieś duszki znajdują się w zasięgu odtwarzacza
  2. Wykonaj test kolizji prostego obwiedni
  3. Wykonaj dokładną kolizję (gdzie potrzebuję pomocy)

Nie mam nic przeciwko zaawansowanym technikom, ponieważ chcę to zrobić, mając na uwadze wszystkie moje wymagania, ale nie jestem pewien, jak do tego podejść. Jakie techniki, a nawet biblioteki do wypróbowania. Wiem, że prawdopodobnie będę musiał stworzyć i przechowywać jakiś kształt, który dokładnie reprezentuje każdą duszkę minus przezroczyste tło.

Czytałem, że na piksel jest wolny, więc biorąc pod uwagę mój duży poziom i liczbę obiektów, nie sądzę, że byłoby to odpowiednie. Patrzyłem również na Box2d, ale nie byłem w stanie znaleźć dużej dokumentacji ani żadnych przykładów tego, jak uruchomić ją z SFML.

Neofita
źródło

Odpowiedzi:

18
  1. Krok pierwszy, utwórz siatkę i zaktualizuj ją dla każdego poruszającego się obiektu.
  2. Sprawdź tylko kolizje między obiektami w tych samych kwadratach.
  3. Sprawdź, czy obwiednia obiektów przecina się (zawiera prostokąt).
  4. Sprawdź, czy piksel nie koliduje idealnie, używając wersji konturowej w niskiej rozdzielczości (patrz fizyka gry).
  5. Wykonaj normalną kontrolę obrysowania zgodnie z opisem w Game Physics (Q 2)

Krok 1:

Utwórz tablicę 2d siatki. Każdy obiekt wie, które kwadraty zajmuje przez swoją pozycję x, y oraz szerokość i wysokość. Jeśli obiekt zostanie odsunięty, usuwa się ze starego kwadratu i aktualizuje nowy kwadrat, który zajmuje.

To zajmuje tylko O ​​(n) łącznie dla n obiektów. Dla dowolnego określonego obiektu O (1).

Krok 2:

Przeprowadź wszystkie kontrole kolizji między obiektami na tych samych kwadratach. Nie ma potrzeby uruchamiania testów na kolizje między obiektami na różnych kwadratach. Obiekt może zajmować do czterech kwadratów, jeśli jest średniej wielkości. Oznacza to bardzo niewiele kontroli.

Krok 3:

Sprawdź przecięcie prostokątów obiektów. Jeśli skrzyżowanie nie istnieje, zatrzymaj się.

Krok 4:

Sprawdź, czy piksele idealnie zderzają się między obrysem obiektów tylko w obszarze przecięcia. Powinno być wystarczająco szybkie. Jeśli nie, utwórz tablicę 2d-boolean niskiej rozdzielczości i sprawdź ją najpierw, jeśli znajdziesz tam kolizje, wystarczy sprawdzić mały segment w wysokiej rozdzielczości 2d-macierzy, oszczędzając ci cenny czas.

Przeczytaj to, aby dowiedzieć się, jak podzielić świat gry na siatkę kwadratów:

Sprawny system wykrywania kolizji

Zapoznaj się z tym, aby dowiedzieć się, jak wykrywać idealne kolizje pikseli .

Fizyka gry / Wykrywanie kolizji 2D AS3

Możesz znacznie poprawić wydajność:

  1. Zapisywanie konturu w niskiej rozdzielczości (1/16) w celu sprawdzenia w pierwszej kolejności.

  2. Sprawdzanie tylko w obszarze, w którym przecinają się dwa prostokąty.

  3. dzieląc kontur z grubsza na segmenty i najpierw sprawdzając kolizje między segmentami.

Zapraszam do komentowania, a ja opracuję.

sprawdź w okolicy skrzyżowania

wolfdawn
źródło
1
Jak powiedział Arthur, zamień kroki 1. i 2. na siatkę, a jeśli chodzi o dokładne wykrywanie kolizji, możesz użyć wersji obrazów o niskiej rozdzielczości.
Markus von Broady,
1
A jeśli naprawdę potrzebujesz, możesz również użyć techniki podobnej do mojej odpowiedzi tutaj: gamedev.stackexchange.com/questions/38481/...
Markus von Broady
Markus wskazuje na dobry pomysł. Powinieneś użyć tablicy 2d-boolean lub tablicy 1d, która jest traktowana jako 2d i możesz zapisać 1/2 1/4 1/8 wersji niskiej rozdzielczości tej tablicy, aby przyspieszyć. Prawdopodobnie nie będzie to konieczne, ponieważ obliczenia na tablicach 2d-boolean są bardzo szybkie. Jest to nadal przydatne narzędzie.
wolfdawn
Jeśli gracz jest całkowicie zamknięty w jednym kwadracie na siatce, możesz sprawdzać tylko z obiektami na tym kwadracie. Gracz może znajdować się jednocześnie na czterech sąsiadujących polach. Czy o to Ci chodziło? Jeśli chodzi o przecięcie prostokątów, tak, wystarczy sprawdzić kolizje, jeśli się przecinają.
wolfdawn
1
Mam nadzieję, że aktualizacja pomoże to wyjaśnić. Po napisaniu kodu możesz go opublikować w przeglądzie kodu i przesłać nam komentarz. codereview.stackexchange.com
wolfdawn