Ich entwickle eine Physik-Engine für ein 2D-Plattformspiel. Ich verwende den Satz der Trennachse für die Kollisionserkennung. Die Bodenfläche besteht aus ausgerichteten Begrenzungsrahmen, wobei der Spieler als achsenausgerichteter Begrenzungsrahmen fungiert. (Speziell verwende ich den Algorithmus aus dem Buch "Realtime Collision Detection", der eine Swept Collision Detection für OBBs mittels SAT durchführt.) Ich verwende in der Kollisionsreaktion einen relativ kleinen Wiederherstellungskoeffizienten (nahe Null), um sicherzustellen, dass die dynamischen Objekte nicht in die Umgebung eindringen.
Der Motor funktioniert größtenteils einwandfrei. Ich mache mir nur Sorgen über einige Randfälle, die möglicherweise auftreten könnten. Zum Beispiel sind in dem Diagramm A, B und C die Bodenoberfläche. Der Spieler bewegt sich links entlang B in Richtung A. Es scheint mir, dass sich die Spielerbox aufgrund von Ungenauigkeiten etwas unterhalb der Box B befinden könnte, wenn sie weiter nach oben und links geht. Wenn es also A erreicht, könnte die untere linke Ecke des Spielers mit der rechten Seite von A kollidieren, was unerwünscht wäre (da der Spieler sich sanft über A bewegen soll). Es scheint, dass ein ähnliches Problem auftreten könnte, wenn sich der Spieler oben auf Feld C befindet und sich nach links in Richtung B bewegt - der äußerste Punkt von B könnte mit der linken Seite des Spielers kollidieren, anstatt dass die untere linke Ecke des Spielers nach oben und links rutscht über B.
Box2D scheint dieses Problem zu lösen, indem es Konnektivitätsinformationen für seine Kantenformen speichert, aber ich bin mir nicht sicher, wie es diese Informationen verwendet, um das Problem zu lösen, und nach dem Betrachten des Codes verstehe ich nicht wirklich, was es tut.
Anregungen wäre sehr dankbar.
Antworten:
Plattform und Physik
Diese Randfälle sind zahlreich. Gute, lustige Plattformer verhalten sich in keiner Weise physisch korrekt, und die Kontrolle und das Verhalten, die Spieler nach Jahren "perfekter" Plattformer wie Mario erwarten, sind mit allgemeinen Techniken, wie sie mit Box2D oder anderen Physik-Engines möglich sind, unglaublich schwierig zu implementieren. Die meisten guten Plattformer verwenden keine generische Physik oder Kollisionsreaktion in ihren Player-Controllern.
Rümpfe erzeugen
Bezüglich Ihrer spezifischen Frage ist es die beste Lösung, keine Boxen mehr als Grundlage zu verwenden. Verwenden Sie eine Reihe verbundener Liniensegmente (einen Rumpf). Dadurch kann sich die Kollisionserkennungs-Engine nur auf die tatsächlich begehbaren Flächen konzentrieren und nicht auf die "gefälschte" Kante zwischen AB und BC. Genau das macht Box2D. Die Formen werden verwendet, um die äußeren Oberflächen zu erzeugen, die miteinander verbunden sind, um einen Rumpf zu bilden.
Sie benötigen dies auch in kachelbasierten Spielen oder in Situationen, in denen zwei AABB-Objekte nebeneinander als Boden fungieren. Die Kollisionsmaschine nimmt diese vertikalen Kanten auf und veranlasst den Spieler, sie einzufangen. Es gibt Hacks, die helfen können, aber das Problem nicht beseitigen. Die Lösung besteht darin, nur ein einziges Liniensegment zu haben, das die Oberfläche darstellt, und nicht eine vollständige 2D-Box.
Sie können die Rümpfe im generischen Fall generieren, indem Sie die Polygone gegeneinander abschneiden und die Schnittpunkte zu einer Kantenliste zusammenfügen.
Schräge Flächen
Da Ihr Beispiel eine Neigung enthält und Sie die Wiederherstellung und andere physikalische Eigenschaften erwähnen, werde ich auf einige andere Probleme hinweisen, die Sie bald bemerken werden. Dies zeigt weiter, warum die generische Kollisionserkennung und -reaktion für Plattformfahrer nicht gut funktioniert. Versuchen Sie zunächst, auf der abgewinkelten Plattform zu stehen, aufzuspringen und dann zu landen. Sie werden wahrscheinlich bemerken, dass der Charakter bei der Landung etwas "rutscht". Das Problem ist, dass die Kontaktnormale, die Sie erzeugen, normalerweise von der abgewinkelten Oberfläche ausgeht. Bei der Lösung der Kollision wird der Spieler dann in diese Richtung hinausgeschoben. Obwohl der Charakter gerade heruntergefallen ist, wird er bei der Landung nach oben und ein wenig nach rechts geschoben, was zum Rutschen führt. Dies kann gehackt werden, indem die relativen Geschwindigkeiten berücksichtigt werden,
Das zweite Problem, das Sie bemerken werden und das viel schwerer zu beheben ist, ist das, was passiert, wenn Sie versuchen, schnell eine Rampe hinunter zu rennen. Der Spieler "hüpft" die Rampe hinunter. Dies ist selbst in den meisten heutigen AAA-Spielen sehr gut sichtbar. Es sieht nicht nur albern aus, aber wenn Ihr Spiel erfordert, dass der Spieler auf dem Boden steht, um zu springen, ist es schwierig, eine Rampe herunterzulaufen und auf halber Höhe herunterzuspringen, da der Spieler die Rampe nur während eines kleinen Abschnitts der Rampe berührt Zeit damit verbracht, es runterzugehen. Eine einfachere Lösung besteht darin, einfach einige Strahlenschläge auszuführen, wenn sich der Spieler bewegt, und die Spielerposition auf die nächstgelegene Oberfläche (wenn sie sich sehr nahe am Spieler befindet) abzusenken, wenn der Spieler nicht springt und zuvor auf dem Boden war.
Sie können auch feststellen, dass der Spieler beim Hochfahren einer Rampe in die Luft startet, wenn Sie versuchen, Geschwindigkeit, Reibung und Rückstellung auf dem Spieler so zu modellieren, als ob er ein normaler starrer Körper wäre. Die Bewegung des Spielers sollte auf horizontale Bewegungen beschränkt sein, es sei denn, er fällt oder springt. Wenn Sie mit älteren Plattformspielern aus dem Goldenen Zeitalter spielen, stellen Sie möglicherweise fest, dass die Horizontalgeschwindigkeit des Spielers zwischen horizontalen und geneigten Oberflächen häufig konstant ist. Dies muss auch beim Auf- und Absteigen berücksichtigt werden.
Es wird auch eine Reihe anderer seltsamer Fälle geben, denen Sie irgendwann begegnen werden. Wenn Sie versuchen, einen guten Plattformer zu entwickeln, ist es wirklich das Beste, einen Platformer-Player-Controller zu implementieren, der von der Physik getrennt ist und das gewünschte Bewegungs- und Steuerverhalten fest codiert, anstatt sich auf allgemeine Physik und Kollisionsreaktionsalgorithmen zu verlassen.
quelle
Ich denke, beide Probleme könnten gelöst werden, indem Ihre Boxen für Kollisionsreaktionszwecke so behandelt werden, als ob sie abgerundete Ecken hätten (mit einem ähnlichen Radius wie Ihr numerischer Fehler). Dadurch wird die effektive kombinierte Oberfläche der Meeting-Ecken zwischen A und B sowie B und C glatter.
Wenn also der sich nach links bewegende SPIELER die Ecke von A berührt, ist die Kollisionsnormale eher diagonal als rein nach rechts, so dass die Bewegung nach links und oben fortgesetzt werden kann.
Eine typischere Lösung für die Überprüfung der mir bekannten Platformer-Physik ist jedoch, den Spieler in eine stärker abgerundete Form zu bringen und das Terrain in Ruhe zu lassen. Überlegen Sie sich insbesondere, ob Sie die Form des Spielers als Kapsel (gedehnt im mittleren Kreis (2D) / Kugel (3D)) definieren möchten - dann sind Ihre Kollisionsnormalen naturgemäß nahezu vertikal, sodass keine Probleme beim Auffangen auftreten.
Sie sagen, Sie verwenden einen Kollisionsalgorithmus speziell für OBBs, sollten aber dennoch in der Lage sein, nach dem Auffinden einer OBB-OBB-Kollision einen weiteren Test gegen eine Form durchzuführen, die sich vollständig innerhalb des OBB befindet.
quelle