2010-10-10 11 views
6

Ich arbeite an einem 3D-Kachel-basierten Spiel und ich benutze AABB Kollisionserkennung. Für jeden Würfel, den der Spieler schneidet, finde ich die Achse, entlang der der Spieler den Würfel am wenigsten schneidet, und schiebe den Spieler entlang dieser Achse aus dem Würfel.Sliding AABB Kollision - an den Kanten stecken

Abhängig von der Reihenfolge, in der die Würfel eingecheckt werden, kann dies zu Problemen beim Gleiten entlang der Kante mehrerer Würfel führen. Ich habe ein Diagramm erstellt, das das Problem erklären sollte:

http://imgur.com/mmK0W.png

  • Pfeil # 1 ist die versuchte Bewegung des Spielers. Die anderen Pfeile sind die Kollisionsantwort.
  • Im linken Diagramm wird die Kollision zuerst mit dem rechten Würfel getestet, wodurch der Spieler nach links und dann nach oben gedrückt wird. (bad)
  • Im rechten Diagramm wird zuerst die Kollision gegen den linken Würfel getestet, wodurch der Spieler nach oben gedrückt wird, wobei der Spieler den anderen Würfel nicht mehr schneidet. (gut)

Irgendwelche Ideen, was der effizienteste Weg, um dies zu lösen sein könnte? Oder irgendwelche besseren Möglichkeiten, die Kollisionsreaktion zu behandeln?

Vielen Dank.

+3

Vielleicht alle Kollisionen prüfen und notieren Sie die Zeit (oder Entfernung) des Kollision zu vermeiden. Wenden Sie nur die Kollision an, die am ehesten eintritt. Optional können Sie den Prozess für den Rest des Zeitschritts fortsetzen. –

+0

Also, wenn ich alle Würfel, die der Spieler mit der Entfernung vom Spieler überschneidet, sortiert und dann nacheinander betrachtet, könnte das funktionieren. Ich denke, es wäre das Beste zu vermeiden, die Dinge in jedem Frame sortieren zu müssen, aber ich bin mir nicht sicher, dass es sehr wichtig wäre, da der Player nur mit bis zu 7 kollidieren könnte? Blöcke auf einmal. Denkst du, dass da etwas zu befürchten ist? – Jeff

Antwort

4

Eine diskrete Implementierung zwingt Sie, nur dann eine kontinuierliche Mathematik in das System zu injizieren, wenn dies erforderlich ist (Würfel/Richtungen überlappen sich).

Für jeden Würfel c1, c2 ... ci mit dem der Benutzer Würfel (uc) zum Zeitpunkt der Prüfung schneidet, möchten Sie herausfinden, welche Würfel zuerst „berührt“ wurde - Es gibt nur einen, wie im wirklichen Leben. Betrachten wir die Richtung d von uc und unter die Menge an uc in ci (überlappend) finden, die Position von cu zur Zeit es "berührt" ci.

bestimmen, welche Würfel wurde „berührt“ erste cj (derjenige, der die meisten Rollback auf der Achse d erforderlich - der früher in der Zeit) und verwenden nur diese eine der Kollisionsreaktion zu berechnen.

Nicht nur Sie werden Genauigkeit erreichen. aber es wird helfen, wenn alle Würfel sich bewegen, unterschiedliche Geschwindigkeiten haben usw.

+0

+1. Ich habe so etwas einmal gemacht, obwohl es ein Problem ist, es zu implementieren und zu debuggen. Sie können mit diesem Ansatz Probleme bekommen, wenn die Bewegung von Objekten von einem Frame zum nächsten nicht entlang einer linearen Linie verläuft, aber ansonsten funktioniert es wirklich gut. Sie müssen sich die vorherige Position (und eventuell die vorherige Geschwindigkeit) jedes Objekts merken, die sich bewegen kann, so dass Sie die Position und Geschwindigkeit der Objekte zu jeder beliebigen Zeit zwischen zwei Frames berechnen können. – Cameron

+0

Ich habe ein kleines Problem damit zu verstehen, was Sie sagen, aber ich denke, diese Antwort würde auch ein Problem haben, wenn der Spieler versucht, in eine Ecke eines Raumes zu gehen. Ich glaube, es wäre notwendig, mehr als einen Block zu berücksichtigen. Ich könnte vielleicht alle Blöcke sortieren, mit denen der Spieler kollidiert, aber ich bin mir nicht sicher, ob es besser wäre, Dinge nicht sortieren zu müssen. – Jeff

+0

Die Wand des Raumes ist genauso zu behandeln wie andere Würfel - dies ist ein besonderer (einfacherer) Fall: Sie prüfen, ob der Würfel außerhalb der Grenzen liegt, und bestimmen mit demselben Algorithmus, wie groß der Würfel ist ist out, dann überprüfen Sie Kollisionen mit anderen Würfeln. Auch hier muss der erste "berührte" (ein anderer Würfel oder die Wand) mit Kollisionsreaktion behandelt werden. Die Wand ist nur ein bestimmtes, sich nicht bewegendes und größeres Objekt, mit dem der Würfel kollidieren kann. –

0

In Ihrem Diagramm scheint es, als wollten Sie die kleinste Bewegung, die die Überlappung zwischen dem Spieler und den Würfeln minimiert. Jeder Würfel mit Überlappung versucht den Spieler in zwei orthogonale Richtungen zu schieben. Kannst du so etwas wie den minimalen Stoß der maximalen Stöße in jede Richtung machen?

+0

Ich denke, das würde Probleme verursachen, wenn der Spieler in eine Ecke läuft. In diesem Fall muss ich den Player um 2 Achsen rückwärts schieben. – Jeff

+0

Okay; Wenn man in 2D denkt, muss der Push eine vertikale und horizontale Komponente haben. Jeder überlappende Würfel kann einen Schub in zwei Richtungen von {N, S, E, W} ausüben. Wenn es mehrere überlappende Cubes gibt, müssen Sie die maximalen Pushs in den Richtungen {N, S} und {E, W} berücksichtigen (alles, was weniger überlappt, kann jedoch ignoriert werden, z. B. ein NS-Push, weil ein EW-Push wird die Arbeit machen). Es gibt höchstens acht Möglichkeiten. Kannst du alle acht in der Reihenfolge der Größenordnung versuchen und den ersten auswählen, der den Spieler von den Würfeln löscht? – Rafe

+0

Leider würde es noch mehr mögliche Sätze in 3 Dimensionen geben. Es wäre wahrscheinlich effizienter, die Blöcke zuerst auf der Grundlage der Entfernung zu sortieren, wie Tom vorgeschlagen hat. – Jeff

0

Sie könnten eine Art hybride breite Phase implementieren, wenn Ihre zwei (oder mehr) stationären Würfel in einer Reihe zu einem größeren Rechteck kombiniert werden können. Testen Sie zuerst das größere Rechteck. Es wird Ihnen die Ergebnisse Ihres grünen Häkchens geben und schneller sein, als jeden Würfel zu überprüfen. Danach, nur wenn es nötig ist, überprüfen Sie die einzelnen Würfel.

+0

Ich versuche zu überlegen, wie ich das auf 3 Dimensionen anwenden würde. Wenn ich eine Form wie ein "L" hätte, die aufsteht, könnte ich 2 Blöcke horizontal oder vertikal kombinieren. Aber ich denke, dass die Reihenfolge, in der ich die Antwort anwenden müsste, von der Position oder Bewegungsrichtung des Spielers abhängen würde. – Jeff

0

Eine Kollision kann nur ein Objekt auf einer Achse verschieben. So ermitteln Sie die zu drückende Achse:

else -- not this 
elseif -- change to this 

if w > h then 
    push x 
elseif h > w then 
    push y 
end 

Dies funktioniert, wenn Ihre Kacheln ausgerichtet sind.

Verwenden Kreise den Stick auf unaligned Fliesen