Jak radzić sobie z wykrywaniem kolizji, aby obiekty nie mogły przechodzić przez ściany?

14

Tworzę strzelankę 2D z przewijaniem bocznym i mam mały problem z wykrywaniem kolizji pocisków. Wszystko, w tym pociski, to obiekty z własnymi wielokątami / metodami aktualizacji.

Problem polega na tym, że pociski poruszają się szybko, a przy 60 klatkach na sekundę (w co gra) pocisk często przeskakuje przez ścianę - ponieważ przesuwa się ona ponad szerokość ściany podczas przerwy między aktualizacjami - i kontynuujcie z radością, ponieważ wielokąty nigdy tak naprawdę się nie pokrywają.

Co mogę z tym zrobić? Jedyne, co udało mi się wymyślić, to narysować linię ze starej pozycji do nowej pozycji i wykonać na niej wykrywanie kolizji, ale dokumentacja slick2d zaleca się rysowanie linii do wykrywania kolizji. Jak mogę to rozwiązać?

Mala
źródło
Nie pełna odpowiedź, więc komentarz. Nigdy nie zalecałbym graficznego rysowania linii, ale matematycznie możesz to zrobić, to tylko proste przecięcie płaszczyzny promienia, aby sprawdzić, czy doszło do kolizji. Następnie możesz wykonać mniejszą stałą detekcję kroku, aby uzyskać dokładny moment (i wszystkie informacje, które się z nim wiążą), kiedy doszło do kolizji, bez konieczności biegania ze stale wyższą częstotliwością, jak sugerują odpowiedzi. Wykonaj mniej kosztowne sprawdzenie, a następnie poświęć czas na uzyskanie tak precyzyjnej odpowiedzi, jak potrzebujesz.
James

Odpowiedzi:

9

Standardowe podejścia to (wybierz jedno):

  1. Zwiększ szerokość granicy ORAZ / LUB zmniejsz maksymalną prędkość pocisku, aby nigdy nie mógł przeskoczyć przez ścianę w jednej aktualizacji (wymaga trochę Pitagorasa, aby obliczyć maksymalne odległości / minimalne szerokości granic);
  2. Wykonuj ciągłe wykrywanie kolizji (CCD), zwykle przez raycasting, aby wykryć kolizję z liniowymi (2) lub płaskimi (3D) powierzchniami przed poruszającym się obiektem. Jest to droższe, ale jest bardziej zaokrąglonym rozwiązaniem. Raycasting względem linii 2D jest dość prosty, ale w tym przypadku musisz zdefiniować wszystkie swoje granice jako wielokąty o prostych krawędziach.

W tym przypadku możesz zamiast tego modelować swoje kule jako promienie - jeśli pasuje to do wyglądu Twojej gry, tak jak w left4kdead . W ten sposób nie musisz przybliżać pocisków jako promieni, ponieważ one już są promieniami. Z punktu widzenia wyglądu może to wyglądać przyzwoicie, jeśli narysujesz linię jaśniejszym punktem na końcu pocisku lub po prostu narysujesz linię jako gradient od światła (koniec pocisku) do ciemności (koniec ogona), nadając mu wygląd ruch.

Zgadzam się, że w większości przypadków używanie grafiki do wykrywania kolizji jest nieco mylące, jednak detekcja kolizji w pikselach jest dokładnie taka i jest przyjętą techniką. Myślę, że wszystko zależy od tego, co chcesz osiągnąć i jak szybko. Jeśli nie potrzebujesz bardzo szybkiej gry z wieloma ciałami i akcją, wybierz ją. Lepiej skorzystaj z jednego z podejść opisanych powyżej.

Inżynier
źródło
Dzięki za świetną odpowiedź - idealnie chciałbym, aby była szybka w ruchu z wieloma ruchomymi ciałami. Powodem, dla którego traktuję pociski jako obiekty fizyczne, jest to, że działają na nie grawitacja jak wszystko inne (więc lekko pochyl się, w zależności od prędkości pocisku itp.). Czy to nie jest dobry sposób na zrobienie tego? To moja pierwsza gra, więc wciąż szukam najlepszych praktyk. Mógłbym również użyć równania parabolicznego, ale nie jestem pewien, jak ustawiłem współczynniki odnoszące się do prędkości / kąta celowania pocisku
Mala
3
To brzmi jak zbyt wiele szczegółów dla pocisków. W prawdziwym życiu, kiedy strzelasz kulą, jest mało prawdopodobne, abyś znalazł tę ślimak z powodu siły rykoszetu, nieprzewidywalności kąta Richochet itp. Albo też, po prostu wchodzi do ciała i pozostaje tam (drzewo, osoba). Po prostu kazałbym im zniknąć lub rykoszetować, a następnie zniknąć wkrótce potem. Skoncentruj się na podstawowej rozgrywce, nie martw się zbytnio o te drobne szczegóły. Realizm najlepiej skupia się na rzeczach, które mają znaczenie.
Inżynier
Tak, przypuszczam, że mogę po prostu użyć linii prostych do pocisków i być może znaleźć sposób, aby nieco później zakrzywiły się w dół, jeśli wydaje się to ważne.
Mala
2
Jeśli prędkość pocisków nie jest zbyt wysoka (tj. Nie tak duża, abyś nie widział, jak poruszają się po ekranie), możesz po prostu zastosować grawitację do ich prędkości, nadal modelując wykrywanie kolizji za pomocą prostych promieni. Użytkownik nie zauważy, że kula porusza się już jako seria linii prostych, niż zauważy, że wszystkie inne obiekty również robią to samo. W przypadku śladów pocisków obliczenie i narysowanie zakrzywionego śladu (splajnu) nie jest trudne i zwiększy iluzję gładkiej krzywej do trajektorii pocisku.
Sean Middleditch
3

Jeśli chcesz, aby twoje pociski zachowywały się jak realistyczne obiekty fizyczne (np. Twoje pociski bardziej przypominają strzały lub kamienie z katapulty niż ostrzał z broni palnej), możesz również spróbować zwiększyć częstotliwość aktualizacji fizyki.

Tak więc, podczas gdy twoja gra może działać z 60 klatkami na sekundę, twoja symulacja fizyczna może działać przy 120 aktualizacjach na sekundę (oto wszechobecny artykuł dotyczący timepeptera, który wyjaśnia dobrą konfigurację fizyki, która może działać z inną prędkością niż pętla renderowania).

Oczywiście zwiększenie interwału aktualizacji silnika fizyki spowoduje większe obciążenie procesora. To podejście jest sensowne tylko wtedy, gdy twoje pociski nie poruszają się bardzo szybko (co zakładałem, ponieważ jesteś w stanie stwierdzić, że twoje pociski poruszają się po łuku).

grzmot
źródło
Dzięki! Skutecznie to robię (podobnie jak pociski w kształcie linii) i mam nadzieję, że będzie to wykonalne, gdy gra stanie się bardziej skomplikowana
Mala