Wie kann ich ein schwebendes Zeichen in Box2D simulieren?

7

Ich erstelle ein Jump'n'Run-Spiel mit der Box2D-Physik-Engine. Die Hauptfigur sollte eine roboterähnliche Kreatur ohne Beine sein, die mit einem Düsentriebwerk über dem Boden schwebt.

Die Bewegung sollte wie die einer fliegenden Untertasse aussehen: Die Kreatur berührt niemals den Boden, kommt aber auch nie zu weit davon entfernt. Welche Konstruktion von Gelenken, Formen und Körpern kann das gut?

Ich habe zunächst versucht, eine Art Pendel herzustellen:

     O        <-- head
     |
    +-+
    |X|       <-- creature's body
    +-+
 ----+-----   <-- ground (pendulum crossing)
     |
     O        <-- heavy body, weld joined to the creature, it does
                  collides with nothing, just pulling the creature
                  down to keep it upright

Das funktioniert jedoch nicht reibungslos und die Kreatur springt zu viel herum. Wie kann ich das Triebwerk gut simulieren?

philipp
quelle

Antworten:

14

UPDATE : Im Laufe der Jahre bin ich ein bisschen sachkundiger geworden und habe festgestellt, dass Setup 2 auf einfachere Weise modelliert werden kann. Ich habe Setup 3 hinzugefügt, was meiner Meinung nach die beste Lösung ist.

Ihre Frage hat mich dazu inspiriert, mit dem RUBE-Editor herumzuspielen , um eine gute Lösung zu finden. Folgendes habe ich mir ausgedacht:

Setup 1

RUBE UFO 1

Beginnen wir mit dem einfacheren links. Es hat das folgende Setup (von unten nach oben):

  1. Ein Radkörper, der hin und her rollen kann
  2. Eine kleine Box (Chassis), die über a am Rad befestigt ist b2RevoluteJoint. Der Fahrgestellkörper darf sich nicht drehen.
  3. Ein Haupt-UFO-Körper (keine Drehung)
  4. Eine b2PrismaticJointVerbindung zwischen dem mittleren Chassis und dem UFO-Gehäuse (dies stellt sicher, dass das UFO immer aufrecht steht).
  5. A b2DistanceJointVerbindet die Mitten des Chassis und des UFO-Körpers. Auf diese Weise kann das UFO auf und ab schwingen und sich schließlich auf einen festgelegten Abstand vom Chassis einstellen (wie schnell dies geschieht, hängt von der Frequenz und dem Dämpfungsverhältnis ab).

Das Ergebnis:

UFO1 gif

Die Idee wäre, nur den UFO-Teil zu rendern und Kollisionsfilterung zu verwenden, damit der Rest der Physik in Ihrem Spiel (mit Ausnahme des Bodens) nicht mit dem Radteil interagiert. Im GIF können Sie sehen, dass das Rad nicht über andere Körper klettert (wie es nicht sollte). Wenn Sie also Schritte in Ihr Spiel aufnehmen möchten, müssen Sie versteckte Rampen hinzufügen und / oder die Form der Physik ändern Boden, damit das Rad die Stufen hinaufsteigen kann.

Setup 2

Wenn Sie mehr als nur vertikale Bewegung wünschen, empfehle ich das zweite Setup: Geben Sie hier die Bildbeschreibung ein

Dieser Fall ist der gleiche wie der erste mit den folgenden Änderungen:

  1. b2Distanceund b2PrismaticJoints von früher sind jetzt mit einem kleinen Zwischenkörper verbunden, dessen Rotation noch nicht erlaubt ist.
  2. Der neue Zwischenkörper ist über b2RevoluteJointden Haupt-UFO-Körper verbunden. Der UFO-Körper darf sich jetzt drehen.
  3. Um den UFO-Körper am Freilauf zu hindern, müssen wir ihn stabilisieren. Glücklicherweise wurde die Methode dafür bereits in dieser Antwort festgelegt . Die vier Distanzgelenke sind am Haupt-UFO-Körper und am neuen Zwischenkörper befestigt. Beim Herumspielen mit dem UFO in RUBE bemerkte ich jedoch, dass die in dieser Antwort vorgeschlagene Konfiguration für parallele Distanzverbindungen instabil war und immer wieder in die im obigen Bild gezeigte Kreuzkonfiguration einrastete. Da das viel stabiler war, habe ich mich dafür entschieden.

Das Ergebnis:

UFO2 gif

Setup 3

Setup 2 ist etwas kompliziert und ein etwas besseres Setup kann mit weniger Körpern und Gelenken erreicht werden:

UFO 3

  1. Rad wie zuvor.
  2. Dieses Mal ist das Rad mit a mit Körper 3 verbunden b2WheelJoint. Dies macht die Notwendigkeit des Gehäusekörpers aus den ersten beiden Einstellungen überflüssig. Das PrismaticJointwird auch nicht mehr benötigt, da sein Verhalten in das eingebaut ist b2WheelJoint.
  3. Ein kleiner Zwischenkörper wird noch benötigt, um das Rad mit dem Hauptkörper zu verbinden. Bei diesem Körper ist die feste Rotationsflagge aus zwei Gründen gesetzt: Er hält das UFO aufrecht (indem die vertikale Achse zwischen dem Rad und sich selbst fixiert wird) und liefert den konstanten Referenzwinkel für den Hauptkörper.
  4. Der kleine Körper an Position 3 ist über a mit dem Hauptkörper verbunden b2WeldJoint. Das b2WeldJointwird hauptsächlich verwendet, um 'an Körpern zusammen zu kleben', aber hier kann die Einschränkung weich gemacht werden, indem die Frequenz und die Dämpfung auf ähnliche Weise wie beim ausgewählt werden b2DistanceJoint.
  5. Der Haupt-UFO-Körper.

UFO 3 gif

Dieses Setup hat im Vergleich zu Setup 2 3 Gelenke und 1 Körper beseitigt. Alle Gelenkanker werden jetzt an logischen Stellen im Modell platziert, im Gegensatz zu den schwebenden b2DistanceJointAnkerpositionen in Setup 2, die viel einfacher zu konstruieren sein sollten und Debuggen im aktuellen Spielcode. Schließlich hat Setup 3 auch den Bonus, nicht zu viel zu schießen, wenn das Rad gegen eine Barriere fährt. Beachten Sie, wie im Setup 2 der UFO-Körper die Radposition überschreitet und zurückschnappt, wenn das Rad mit hoher Geschwindigkeit auf ein Hindernis stößt. Der Boden b2RevoluteJointtrennt sich unter der Last. Dies passiert nicht b2WheelJointin Setup 3.

Was auch immer Sie am Ende tun, ich empfehle dringend, es in RUBE auszuprobieren. Es ist eine großartige Möglichkeit, um zu versuchen, unterhaltsame physikalische Lösungen zu finden.

Nautische Meile
quelle
Danke für diese coole Antwort, ich werde das überprüfen! Übrigens: Ich habe bereits RUBE und ich habe bereits damit gespielt…
philipp
Das ist cool, funktioniert wirklich gut!
Philipp
Kein Problem, ich bin froh, dass ich helfen konnte :)
NauticalMile
3

Die Antwort von NauticalMile ist großartig (und Bonuspunkte für die animierten Killer-Diagramme). Um einen alternativen Vorschlag zu machen, der nicht unter denselben Problemen leidet (die Radkollision hindert Sie daran, sich an Objekten vorbei zu bewegen, die ein schwebender Körper mühelos durchqueren sollte, schlage ich vor, etwas zu modellieren, das der Realität Ihrer Situation besser entspricht Verwenden Sie keine Kollisionen und Federn mit starren Körpern.

Modellieren Sie Ihren Charakter wie gewohnt als starre Box, aber bei jedem Update wird ein Raycast direkt nach unten (in Richtung Ihres Jet-Schubes) durchgeführt und der Abstand zwischen dem Charakter und dem nächsten kollidierbaren Objekt gemessen. Wenden Sie dann einen Aufwärtsimpuls auf den Körper Ihres Charakters an, der umgekehrt proportional zur Entfernung vom Boden ist. Je näher Sie dem Boden sind, desto größer ist der Impuls. Dies kann ein linearer Anteil oder ein exponentieller Anteil sein, aber Sie möchten nicht, dass er zu groß ist (dh in den Himmel schießt), sodass Sie ihn über einen bestimmten Bereich hinaus dämpfen möchten. Aber im Grunde sollte es ein Gleichgewicht gegen die Auswirkungen der Schwerkraft erreichen, um die Wirkung einer Feder zu erzielen - je näher Sie dem Boden kommen, desto mehr Energie verleiht die Feder, desto weiter entfernt, desto weniger stärkt sie Sie. Kombiniert mit einem Dämpfungsfaktor für die Bewegung,

NB: Diese Kraft sollte darauf beschränkt sein, nur vertikal auf Ihren Körper zu wirken. Andernfalls geraten Sie in reale Probleme, in denen Ihr Charakter instabil ist und vorwärts oder rückwärts taumeln möchte, je nachdem, was sich darunter befindet oder in welchem ​​Winkel sich der Charakter befindet.

Das Springen fügt dieser Kraft dann einfach einen zusätzlichen vertikalen Faktor hinzu - Sie können nicht unendlich hoch springen, aber es hat die zusätzliche Nuance, dass Sie einen zusätzlichen erhalten können, wenn Sie den Sprung richtig einstellen (etwa kurz nach dem Herunterfallen aus einer Höhe) Höhe beim Sprung durch Ausnutzung des Bounce-Effekts.

Dies sollte den Effekt haben, dass eine reibungslose Bewegung über kleine Hindernisse möglich ist, ohne dass Ihre horizontale Geschwindigkeit beeinträchtigt wird. Wenn das Hindernis unter den Jet Raycast fällt, verschiebt sich der Charakter nach oben, verlangsamt sich aber überhaupt nicht.

Tatsächlich kann ein einzelner Raycast instabil sein, insbesondere wenn Sie sich über unwegsames Gelände bewegen. Ich würde vielleicht zwei oder drei Raycasts machen und einen Durchschnitt der Entfernung nehmen; Gewichtung, wenn Sie möchten, oder Verwerfen von Messungen mit einer bestimmten Abweichung vom Durchschnitt. Was Sie nicht wollen, ist ein Fall, in dem sich der Charakter über eine sehr schmale Lücke in einer ansonsten flachen Oberfläche der Welt bewegt und stark nach unten fällt, weil der Strahl zufällig direkt in diese Lücke eindringt.

MrCranky
quelle
1
+1 Ich bin auch ein großer Fan der Modellierung von Spielmechaniken, die eng auf ihrem physischen Verhalten basieren. Dies ist ein weiterer guter Weg, dies zu tun. Der Kompromiss ist jedoch der Determinismus des Verhaltens. Was passiert zum Beispiel, wenn das Schiff auf den Kopf gestellt wird? Es wird immer kleine Probleme wie diese geben, die wir vorhersagen und bewältigen müssen.
NauticalMile
1
Jetzt, wo ich darüber nachdenke, könnte es einen noch besseren Weg geben: Was ist, wenn Sie anstelle des Radgelenks 3 Raycasts vom UFO machen, wie Sie gesagt haben, aber anstelle eines einzelnen UFO-Körpers die Distanzgelenke von meinem verwenden Antwort an einem nicht rotierenden Kern angebracht. Auf diese Weise könnten Sie (fast) eine gewisse Stabilität haben, das UFO wackeln lassen und die Probleme beim Klettern im Gelände aus meiner Antwort vermeiden. Gedanken?
NauticalMile