Wie gehe ich mit der Kollisionserkennung um, damit schnelle Objekte nicht durch Wände gelangen können?

14

Ich erstelle einen 2D-Side-Scrolling-Shooter und habe ein kleines Problem mit der Kollisionserkennung für die Kugeln. Alles, einschließlich der Aufzählungszeichen, sind Objekte mit eigenen Polygonen / Aktualisierungsmethoden.

Das Problem ist, dass die Kugeln schnell verlaufen und bei 60 Bildern pro Sekunde (mit der das Spiel ausgeführt wird) eine Kugel oft direkt durch eine Wand springt - da sie sich während des Aktualisierungsintervalls mehr als die Breite der Wand bewegt - und mache glücklich weiter, denn die Polygone werden sich nie wirklich überlappen.

Was kann ich dagegen tun? Das Einzige, was mir eingefallen ist, ist, eine Linie von der alten Position zur neuen Position zu ziehen und eine Kollisionserkennung durchzuführen. Die slick2d-Dokumentation empfiehlt jedoch, eine Linie zur Kollisionserkennung zu zeichnen. Wie kann ich das lösen?

Mala
quelle
Keine vollständige Antwort, also ein Kommentar. Ich würde niemals empfehlen, eine Linie grafisch zu zeichnen, aber Sie können dies mathematisch tun, es ist nur ein einfacher Schnittpunkt in der Strahlenebene, um zu sehen, ob die Kollision stattgefunden hat. Sie können dann eine kleinere Erkennung fester Schritte durchführen, um den genauen Zeitpunkt (und alle damit verbundenen Informationen) zu ermitteln, zu dem die Kollision stattgefunden hat, ohne ständig mit einer höheren Geschwindigkeit laufen zu müssen, wie in den Antworten angegeben. Führen Sie eine kostengünstigere Überprüfung durch, und verbringen Sie dann die Zeit damit, eine Antwort so präzise wie möglich zu erhalten.
James

Antworten:

9

Die Standardansätze sind (bitte auswählen):

  1. Erhöhen Sie Ihre Begrenzungsbreite UND / ODER verringern Sie die maximale Geschwindigkeit Ihres Geschosses, damit es niemals in einem einzigen Update durch eine Wand springen kann (erfordert ein wenig Pythagoras, um die maximalen Abstände / minimalen Begrenzungsbreiten zu ermitteln).
  2. Führen Sie eine kontinuierliche Kollisionserkennung (Continuous Collision Detection, CCD) durch, in der Regel durch Raycasting, um Kollisionen mit linearen (2) oder ebenen (3D) Oberflächen vor dem sich bewegenden Objekt zu erkennen. Dies ist teurer, aber eine rundere Lösung. Raycasting gegen 2D-Linien ist ziemlich einfach, aber in diesem Fall müssen Sie alle Ihre Grenzen als Polygone mit gerader Kante definieren.

In diesem Fall können Sie Ihre Kugeln stattdessen als Strahlen modellieren - wenn dies zum Look & Feel Ihres Spiels passt, wie in left4kdead . Auf diese Weise müssen Sie Kugeln nicht als Strahlen approximieren, da es sich bereits um Strahlen handelt. Unter dem Gesichtspunkt des Aussehens kann dies anständig aussehen, wenn Sie die Linie mit einem helleren Punkt am Kugelende zeichnen oder die Linie einfach als Verlauf von hell (Kugelende) nach dunkel (Heckende) zeichnen und ihr das Aussehen von geben Bewegung.

Ich würde zustimmen, dass die Verwendung von Grafiken für die Kollisionserkennung unter den meisten Umständen ein wenig irreführend ist, jedoch ist die pixelgenaue Kollisionserkennung genau das und eine akzeptierte Technik. Ich denke, alles hängt davon ab, was Sie erreichen möchten und wie schnell. Wenn du kein sehr schnelles Spiel mit vielen Körpern + Action brauchst, dann mach es. Anderenfalls ist es besser, einen der oben beschriebenen Ansätze zu verwenden.

Ingenieur
quelle
Vielen Dank für die tolle Antwort - im Idealfall möchte ich, dass es mit vielen sich bewegenden Körpern schnell geht. Der Grund, warum ich Kugeln als physische Objekte behandle, besteht darin, dass sie wie alles andere von der Schwerkraft beeinflusst werden (also je nach Geschwindigkeit der Kugel usw. leicht nach unten biegen). Ist das nicht ein guter Weg, es zu tun? Dies ist mein erstes Spiel, daher bin ich immer noch auf der Suche nach Best Practices. Ich könnte auch eine parabolische Gleichung verwenden, aber ich bin nicht sicher, wie ich die Koeffizienten in Bezug auf die Geschwindigkeit / den Zielwinkel der Kugel eingestellt habe
Mala,
3
Es klingt zu detailliert für Kugeln. Wenn Sie eine Kugel abschießen, ist es im wirklichen Leben unwahrscheinlich, dass Sie diese Kugel jemals finden, da die Kraft des Abprallers, die Unvorhersehbarkeit des Richochet-Winkels usw. nicht vorhergesehen werden kann. Ich würde sie einfach verschwinden lassen oder abprallen und kurz danach wieder verschwinden lassen. Konzentriere dich auf dein Kern-Gameplay, mach dir keine Sorgen um diese kleinen Details. Realismus konzentriert sich am besten auf die Dinge, die wichtig sind.
Ingenieur
Ja, ich nehme an, ich kann nur gerade Linien für Aufzählungszeichen verwenden und vielleicht einen Weg finden, um sie später etwas nach unten zu krümmen, wenn es wichtig erscheint.
Mala
2
Wenn die Geschwindigkeit der Kugeln nicht zu hoch ist (dh nicht so schnell, dass Sie sie nicht über den Bildschirm bewegen können), können Sie einfach die Schwerkraft auf ihre Geschwindigkeit anwenden, während Sie ihre Kollisionserkennung mit einfachen Strahlen modellieren. Der Benutzer wird nicht mehr bemerken, dass sich die Kugel als eine Reihe von geraden Linien bewegt, als dass er bemerken wird, dass auch alle Ihre anderen Objekte dasselbe tun. Bei Geschossspuren ist das Berechnen und Zeichnen einer gekrümmten Spur (Spline) nicht schwierig und erhöht die Illusion einer glatten Kurve zur Flugbahn des Geschosses.
Sean Middleditch
3

Wenn Sie möchten, dass sich Ihre Kugeln wie realistische physische Objekte verhalten (z. B. sind Ihre Kugeln eher wie Pfeile oder Steine ​​eines Katapults als wie Schüsse), können Sie auch versuchen, die Häufigkeit Ihrer physischen Aktualisierungen zu erhöhen.

Während Ihr Spiel möglicherweise mit 60 Bildern pro Sekunde läuft, könnte Ihre Physiksimulation mit 120 Aktualisierungen pro Sekunde laufen (hier ist der allgegenwärtige Fix Ihres Timestep- Artikels, der ein gutes Physik-Setup erklärt, das mit einer anderen Geschwindigkeit als die Render-Schleife laufen kann).

Wenn Sie das Update-Intervall für die Physik-Engine erhöhen, wird die CPU natürlich stärker belastet. Dieser Ansatz ist nur sinnvoll, wenn sich Ihre Projektile nicht sehr schnell bewegen (was ich angenommen habe, da Sie feststellen können, dass sich Ihre Projektile im Bogen bewegen).

Blödmann
quelle
Vielen Dank! Ich mache das effektiv (und verwende auch linienförmige Projektile) und hoffe, dass es machbar bleibt, wenn das Spiel komplizierter wird
Mala