Wenn ich weiß, dass eine bestimmte Aktion zu einer Kollision führt, sollte ich die Aktion trotzdem zulassen?

7

Ich habe meine Spiel-Engine fertig programmiert und jetzt, da ich sie getestet habe, habe ich einige Grafikprobleme bemerkt.

Das große Problem ist, dass wenn ein Spieler versucht, gegen eine Wand zu drücken, sein Charakter dagegen "wackelt", wenn er ständig versucht, in den Raum der Wand einzudringen, und die Kollisionserkennung ihn ständig wieder nach draußen drückt.

Was ist der richtige Weg, um mit einer solchen Situation umzugehen?

Mein erster Instinkt war, wenn eine Bewegung in eine bestimmte Richtung eine Kollision verursacht, die Bewegung in diese Richtung zu deaktivieren, bis sich die Position der Entität geändert hat. Wenn ein Objekt auf eine Plattform fällt, deaktivieren Sie die Schwerkraft, bis sich das Objekt nicht mehr über einer Plattform befindet.

Gibt es eine bessere Möglichkeit, wiederholte Kollisionserkennungen zwischen denselben beiden Objekten im selben überlappenden Raum aufzulösen?

Raben-Träumer
quelle

Antworten:

5

Zum Beispiel über Zeichenkollisionen mit einer Wand (ich verwende einige willkürliche Werte als Beispiel): Wenn Sie 10 Einheiten (z. B. Pixel) von einer Wand entfernt sind und ein einzelner Schritt normalerweise 20 Einheiten in diese Richtung bewegt, wird die Das richtige Verhalten ist, dass dein Charakter 10 Einheiten bewegt und dort anhält. Wenn Sie stattdessen die Aktion abbrechen, bleiben Sie 10 Einheiten von der Wand entfernt, was nicht das ist, was Sie möchten.

Eine Möglichkeit, dies zu tun, besteht darin, den Charakter um den vollen Betrag zu bewegen, dann die Kollision und ihre Tiefe zu erkennen, dh wie stark sich die Begrenzungsrahmen des Charakters und der Wand überlappen, und den Charakter um denselben Betrag zurück zu bewegen. Wenn du das richtig machst, solltest du kein "Wackel" -Verhalten von deinem Charakter bekommen, er wird einfach gegen die Wand drücken und dort anhalten. Wenn er wackelt, bewegen Sie ihn wahrscheinlich zu stark zurück (Sie bewegen ihn wahrscheinlich zurück in die Position, in der er sich vor der Kollision befand, anstatt ihn gegen die Wandgrenze zu klemmen).

Abgesehen davon sehe ich die Schwerkraft normalerweise als Sonderfall. In den meisten Implementierungen, die ich gesehen habe, speichert das Zeichen ein onFloorFlag und die Schwerkraft wird nur angewendet, wenn dieses Flag falsch ist.

Bearbeiten: Ich denke, Sie könnten dieses letzte Konzept erweitern und zusätzliche Flags wie touchingRightWalloder erstellen touchingLeftWall, aber nur, wenn die Grenzen des Charakters und der Wand genau übereinstimmen . In diesem Fall könnten Sie die Bewegung möglicherweise ganz umgehen. Wenn die Grenzen jedoch nicht genau übereinstimmen, sollten Sie die Bewegung stattfinden lassen und das Kollisionserkennungssystem alle Kreuzungen auflösen lassen.

David Gouveia
quelle
So gehe ich derzeit mit Kollisionen um. Das "Wackeln" sieht eher so aus, als ob das Sprite vibriert, als eine erkennbare Menge an Vorwärts / Rückwärts.
Raven Dreamer
2
Berechnen Sie die Schnitttiefe richtig? Versuchen Sie, die Positionswerte und die Schnitttiefe des Charakters mit denen zu debuggen, die Sie erwarten würden. Ich habe das schon einmal ohne Vibrationen gemacht. Könnte es sich auch um ein Subpixel-Gleitkomma-Problem handeln? Wenn dies der Fall ist, runden Sie Ihre Werte. Überprüfen Sie abschließend das Platformer-Beispiel des XNA.
David Gouveia
Ehrlich gesagt denke ich, es liegt nur daran, dass die E / A (die die Entität bewegt) zu einem anderen Zeitpunkt als die Kollisionserkennung erfolgt, was bedeutet, dass sich die beiden Entitäten überlappen, bis die Spiel-Engine die Aktualisierungsschleife des Kollisionssubsystems erreicht.
Raven Dreamer
Aber werden die E / A- und Kollisionserkennungs-Subsysteme nicht in derselben Iteration Ihrer Aktualisierungsschleife aktualisiert? Ich konnte nur sehen, dass dies einen Unterschied macht, wenn Ihre Rendering-Schleife vollständig getrennt war und irgendwie zwischen den Aktualisierungen Ihrer Subsysteme aufgerufen werden konnte , oder wenn Sie diese Verarbeitung zwischen mehreren Frames ausdehnen .
David Gouveia
Der gesamte Prozess ist normalerweise [E / A -> Kollisionserkennung -> Kollisionsauflösung] -> [Rendern]. Selbst wenn die Teile "Aktualisieren" und "Rendern" mit unterschiedlichen Raten aufgerufen werden, sollten Sie Ihre Objekte niemals in einem Zwischenzustand sehen können (dh nach E / A, aber vor der Kollisionserkennung oder nach der Kollisionserkennung, aber vor der Kollisionsauflösung). Sie werden immer sehen, wie Ihr Charakter gerendert wird, nachdem alle Phasen des Updates angewendet wurden. Es sollte also keine Rolle spielen, ob sie in verschiedenen Schritten verarbeitet werden oder nicht.
David Gouveia
2

Dieses Problem tritt normalerweise auf, wenn der Code die Positionen festklemmt, bevor eine Kollision erkannt wird. Dh:

MoveCharacter();
ClampPosition();
CheckCollision();
DrawFrame();

anstatt

MoveCharacer();
CheckCollision();
ClampPosition();
DrawFrame();

Der Grund, warum es "wackelt", ist, dass die Prüfung erfolgt, nachdem der Charakter an einem "sicheren" Ort festgeklemmt wurde, aber dass sich der Charakter zum Zeitpunkt der Prüfung an einem nicht kollidierenden Ort befindet, damit die Engine dem Charakter erlaubt, fortzufahren Bewegen Sie sich, dann wird das Zeichen gezeichnet und im nächsten Frame, in dem die Prüfung fehlschlägt, wird Clamp aufgerufen, wodurch das Zeichen an den sicheren Ort zurückschnappt.

Casey
quelle
1
Ich sehe nicht wirklich, wie das Sinn macht. Wie könnte die Klemmung jemals passieren, bevor nach Kollisionen gesucht wird, wenn Sie die Ergebnisse Ihrer Kollisionen benötigen, um zu wissen, gegen welche Werte Sie überhaupt klemmen müssen?
David Gouveia
Was wirklich passiert, ist, dass der Charakter gezeichnet wird, bevor er im nächsten Frame an die richtige Position verschoben wird, anstatt an die richtige Position verschoben zu werden, bevor der aktuelle Frame gezeichnet wird.
Casey
0

Ich hatte kürzlich das gleiche Problem und habe es folgendermaßen behoben:

Bewegen Sie das Objekt und suchen Sie nach einer Kollision. Wenn eine Kollision gefunden wird, platzieren Sie das Objekt außerhalb des kollidierenden Objekts. zeichne das Objekt.

Der Spieler könnte ohne Wackeln gegen die Wand rennen, da er vor dem Ziehen an der Seite des Objekts platziert wird.

Johan
quelle
0

Mithilfe der Vektor- / Ebenenmathematik können Sie den genauen Kollisionspunkt mit der Wand berechnen, der im nächsten Frame auftreten wird. Dies setzt voraus, dass Ihr Charakter eine Geschwindigkeit hat, mit der Sie den Bewegungsvektor berechnen können, der im nächsten Frame auftreten wird. Nachdem Sie den Kollisionspunkt gefunden haben, können Sie den Gleitvektor berechnen, der Ihren Charakter entlang der Wand bewegt. Dieser Vektor kann tatsächlich mit einer anderen Wand kollidieren.

Zurück zu Ihrer Frage, sollten Sie die genaue Position der Kollision berechnen, an der sich Ihr Charakter befinden sollte und was dann tatsächlich passieren sollte. Wenn dies eine Wand und ihr FPS-Spiel ist, lassen Sie den Charakter daran entlang gleiten.

marcinj
quelle