Diese Frage ist eine "Folgefrage" aus meiner vorherigen Frage zur Kollisionserkennung und -behebung, die Sie hier finden .
Wenn Sie die vorherige Frage nicht lesen möchten, finden Sie hier eine kurze Beschreibung der Funktionsweise meiner Physik-Engine:
Jede physische Entität wird in einer Klasse namens SSSPBody gespeichert.
Es werden nur AABBs unterstützt.
Jeder SSSPBody wird in einer Klasse namens SSSPWorld gespeichert, die jeden Körper aktualisiert und mit der Schwerkraft umgeht.
Jeder Frame, SSSPWorld aktualisiert jeden Körper.
Jeder aktualisierte Körper sucht in einem räumlichen Hash nach in der Nähe befindlichen Körpern und prüft, ob sie Kollisionen mit ihnen erkennen müssen. Wenn ja, rufen sie ein "Kollisions" -Ereignis auf und prüfen, ob sie Kollisionen mit ihnen auflösen müssen. Wenn ja, berechnen sie den Penetrationsvektor und die gerichtete Überlappung und ändern dann ihre Position, um die Penetration aufzulösen.
Wenn ein Körper mit einem anderen kollidiert, überträgt er seine Geschwindigkeit auf den anderen, indem er einfach die Geschwindigkeit des Körpers auf seine eigene setzt.
Ein Körper ist Geschwindigkeit wird auf 0 gesetzt, wenn er seine Position seit dem letzten Frame nicht geändert hat. Wenn es auch mit einem sich bewegenden Körper kollidiert (z. B. einem Aufzug oder einer sich bewegenden Plattform), berechnet es die Bewegungsdifferenz des Aufzugs, um festzustellen, ob sich der Körper nicht von seiner letzten Position bewegt hat.
Außerdem ruft ein Körper ein "Crushed" -Ereignis auf, wenn alle seine AABB-Ecken etwas in einem Frame überlappen.
Dies ist der vollständige Quellcode meines Spiels. Es ist in drei Projekte unterteilt. SFMLStart ist eine einfache Bibliothek, die die Eingabe, das Zeichnen und das Aktualisieren von Entitäten verwaltet. SFMLStartPhysics ist die wichtigste, bei der die Klassen SSSPBody und SSSPWorld vorhanden sind. PlatformerPhysicsTest ist das Spielprojekt, das die gesamte Spielelogik enthält.
Und dies ist die "Update" -Methode in der SSSPBody -Klasse, kommentiert und vereinfacht. Sie können sich das nur ansehen, wenn Sie keine Lust haben, das gesamte SFMLStartSimplePhysics-Projekt zu betrachten. (Und selbst wenn Sie dies tun, sollten Sie sich dies trotzdem ansehen, da es kommentiert ist.)
Das GIF zeigt zwei Probleme.
- Wenn Körper in einer anderen Reihenfolge platziert werden, treten unterschiedliche Ergebnisse auf. Die Kisten auf der linken Seite sind identisch mit den Kisten auf der rechten Seite, nur in umgekehrter Reihenfolge (im Editor).
- Beide Kisten sollten nach oben geschoben werden. In der Situation links werden keine Kisten befördert. Auf der rechten Seite ist nur einer von ihnen. Beide Situationen sind nicht beabsichtigt.
Erstes Problem: Reihenfolge der Aktualisierung
Das ist ziemlich einfach zu verstehen. In der Situation links wird die oberste Kiste vor der anderen aktualisiert. Selbst wenn die Kiste auf der Unterseite die Geschwindigkeit auf die andere "überträgt", muss sie auf das nächste Bild warten, um sich zu bewegen. Da es sich nicht bewegte, ist die Geschwindigkeit der unteren Kiste auf 0 gesetzt.
Ich habe keine Ahnung, wie ich das beheben soll. Ich würde es vorziehen, wenn die Lösung nicht davon abhängt, die Aktualisierungsliste zu "sortieren", da ich das Gefühl habe, dass ich im gesamten Design der Physik-Engine etwas falsch mache.
Wie gehen die wichtigsten Physik-Engines (Box2D, Bullet, Chipmunk) mit der Update-Bestellung um?
Zweites Problem: Nur eine Kiste wird zur Decke befördert
Ich verstehe noch nicht, warum das passiert. Was die "Feder" -Entität tut, ist die Geschwindigkeit des Körpers auf -4000 einzustellen und sie auf der Feder selbst neu zu positionieren. Auch wenn ich den Neupositionierungscode deaktiviere, tritt das Problem weiterhin auf.
Meine Idee ist, dass, wenn die untere Kiste mit der oberen Kiste kollidiert, ihre Geschwindigkeit auf 0 gesetzt wird. Ich bin nicht sicher, warum dies passiert.
Trotz der Möglichkeit, wie jemand auszusehen, der beim ersten Problem aufgibt, habe ich den gesamten Quellcode des Projekts oben gepostet. Ich habe nichts, um es zu beweisen, aber glauben Sie mir, ich habe mich sehr bemüht, das zu beheben, aber ich konnte einfach keine Lösung finden und ich habe noch keine Erfahrung mit Physik und Kollisionen. Ich habe mehr als eine Woche lang versucht, diese beiden Probleme zu lösen, und jetzt bin ich verzweifelt.
Ich glaube nicht, dass ich alleine eine Lösung finden kann, ohne viele Features aus dem Spiel zu streichen (z. B. Geschwindigkeitsübertragung und Federn).
Vielen Dank für die Zeit, die Sie mit dem Lesen dieser Frage verbracht haben, und noch mehr, wenn Sie versuchen, eine Lösung oder einen Vorschlag zu finden.