Wie kann ich Swinging einfach in ein Platformer-Spiel implementieren?

9

Ich entwickle ein Spiel, in dem Spieler mit Seilen schwingen können (genau wie Spiderman oder Bionic Commando ), und ich habe Probleme, dieses Verhalten zu implementieren. Kann mir jemand helfen, wie das geht, ich meine Physikformeln und so weiter. Bis jetzt habe ich 3 Ideen. Man benutzt den Frühling, aber er verbraucht viel Zeit und manchmal ist er nervös. Die anderen beiden versuchen, den nächsten Schritt zu berechnen (einen über die Berechnung der potentiellen Energie und einen über die Berechnung des Drehmoments), und beide stürzen fast ab, wenn der Schauspieler versucht zu schwingen.

Hier ist der Code, den ich geschrieben habe, um das Drehmoment zu berechnen:

float dx = Runner->getPosition().x - ancher.x; 
float dy = Runner->getPosition().y - ancher.y;
float t0 = atan2(dy,dx); //my current angle
float k = ((dy) *vx - (dx) * vy) / (dx * dx+dy * dy); //previus angular velocity
k -= gravity * cos(t0) *dt; // new angular velocity (gravity is positive)
t0 += k * dt - acc * cos(t0) *dt * dt / 2; // rotate the rope
float dx1 = r0 * cos(t0); // new position (r0 is rope length)
float dy1 = r0 * sin(t0);
vx = (dx1 - dx) / dt; //calculate velocity
vy = (dy1 - dy) / dt;
Ali1S232
quelle
Relevant (zur Herstellung eines Seils): 2D-Kollisionserkennung von
Seilen
@JonathanHobbs Die Antwort in dieser Frage ist genau, wie ich versuche, mein Seil mit einer Ausnahme zu implementieren, da in meinem Fall eine Kollision unerwünscht ist, setze ich jedes Seilteil als Sensor, damit sie sich frei bewegen können, ohne ineinander zu stecken.
Ali1S232
Was ist mit einem einfachen Seilpendel + einigen Animationen, die seilig erscheinen? Ich glaube nicht, dass alte Spiele wie Bionic Commando etwas anderes als Pendel hatten.
user712092
@user diese Pendelidee sollte gut funktionieren. Aber in meinem Fall gab es entweder wegen der schnellen Bewegung des Spielers oder meiner schlechten Implementierung keine guten Ergebnisse.
Ali1S232
@ Gajet versuchen, einige Debug-Zeichnungen zu machen, bis Sie es richtig machen? Diese Pendellinie kann in Box2D als ausreichend dünne Box ausgeführt werden, um Kollisionen zu erhalten (und sie möglicherweise von der Physik auszuschließen und von Hand zu bewegen?).
user712092

Antworten:

6

Wenn Sie einen starren Schwung wünschen, damit der Abstand zum Drehpunkt konstant ist, behandeln Sie das Zeichen einfach als einen Punkt auf einem Kreis, der am Drehpunkt zentriert ist. Geben Sie ihm eine eindimensionale Winkelgeschwindigkeit (entlang des Kreises). In jedem Frame sollte die Winkelbeschleunigung sein accelerationDueToGravity * cos(angleOfPlayerOnCircle)(wobei 0 Grad nach rechts zeigen).

Wenn Sie möchten, dass das Seil länger / kürzer wird, können Sie das obige Schema verwenden und einfach den Radius jedes Rahmens variieren.

BlueRaja - Danny Pflughoeft
quelle
Ihre Antwort war mein zweiter Versuch, aber es bewegt sich viel schneller, als ich sollte, um meine Frage zu bearbeiten und meinen Code hinzuzufügen. Vielleicht können Sie erkennen, wo das Problem liegt.
Ali1S232
3

Nach vielen Versuchen ging ich mit box2d.

Es gibt im Allgemeinen zwei Ansätze für diese Simulation oder zumindest habe ich 2 gefunden:

  1. Eine besteht darin, einige Kreisformen zu verwenden und sie mit entfernten Verbindungen zu verbinden.
  2. und das andere ist, Rechtecke für die Kette selbst zu machen und sie dann mit Drehgelenken zu befestigen

In jedem Szenario muss man einen Ancher haben (was in meinem Fall eine statische Box war). Es ist besser, wenn Sie das Gewicht der Seilteile verringern (entweder verwenden Sie Kreisformen oder Rechteckformen). Um beispielsweise eine realistischere Physik zu erzielen, habe ich deren Dichte auf 0,1 eingestellt und für die am Ende des Seils angeschlossene Box die Dichte 10 verwendet.

Eine andere Sache, die Sie sich Sorgen machen müssen, wie Ihr Seilsegment aufeinander reagiert. Ich wollte nur, dass sich mein Seil in der Szene frei bewegt, also markierte ich alle Seilbefestigungen als Sensoren. Möglicherweise benötigen Sie einen anderen Ansatz.

Das nächste, worüber Sie sich Sorgen machen müssen, ist die Anzahl der Iterationen, die Sie für das Welt-Update durchführen: Für ein niedriges Seilsegment (möglicherweise höchstens 8) ist es nicht erforderlich, einen hohen Iterationswert zu verwenden, möglicherweise 10/10, den box2d selbst vorgeschlagen hat ist genug, aber wenn Sie die Anzahl der Segmente erhöhen, habe ich zum Beispiel 30 Segmente ausprobiert. Bei einer geringen Anzahl von Iterationen scheint Ihr Seil die Länge mehr zu erhöhen, als es sollte. Sie benötigen also möglicherweise 40/40 Iterationen, um diese Situationen zu lösen.

Nach einigen Tests scheint Box 2d für Szenen mit Objektgrößen von 0,1 m bis 10 m ausgelegt zu sein, und die für große Szenen empfohlene maximale Größe liegt bei etwa 50 x 50 m. Grundsätzlich müssen Sie Ihr Objekt verkleinern, um diesen Parametern zu entsprechen. In meinem Fall habe ich zuerst versucht, Pixelpositionen direkt an box2d zu übergeben, aber es schien, als gäbe es einige Geschwindigkeitsbegrenzungen, die verhindern, dass sich die Welt so schnell bewegt, wie es sein sollte. Deshalb musste ich meine Szene ungefähr 64 Mal skalieren, um die besten Ergebnisse zu erzielen. Obwohl ich mich nicht selbst getestet habe, gibt es in Box2d einige Einschränkungen, die Sie daran hindern, größere Szenen zu verwenden. Zum Beispiel gibt es einen definierten Wert in der b2Setting.hDatei, mit dem #define b2_maxTranslation 2.0fSie die Einstellungen für box2d ändern können, der jedoch nicht empfohlen wird.

Ali1S232
quelle
Warum ist es falsch mit box2d, mir eine Abwertung zu verdienen?
Ali1S232
Dies beantwortet die Frage nicht. Schreiben Sie zumindest, wie Sie es mit Box2D zum Laufen gebracht haben.
Bummzack
@ Bummzack: Ok, ich werde das zu meiner Antwort hinzufügen
Ali1S232
Wenn Sie dies als Ihre Antwort akzeptieren, ist Ihre Frage fehlerhaft. Die segmentierte Seilphysik unterscheidet sich stark von der von Ihnen beschriebenen.
AttackingHobo
@attackingHobo: Die Frage war zu diesem Zeitpunkt korrekt, aber als ich meinen Code in box2d umwandelte, fand ich heraus, dass ich ohne großen Aufwand segmentierte Seilphysik implementieren kann. und es ist nicht viel anders, stellen Sie sich meine Frage als nur ein Segment eines segmentierten Seils vor. und fast alle meine Lösungen waren Möglichkeiten, ein Seil im Kreisstil ohne box2d zu implementieren.
Ali1S232
2

Haben Sie darüber nachgedacht, die Geschwindigkeit der Schwungbewegung zu verlangsamen, je nachdem, wie weit das Seil von der Lotlinie (der Mitte) entfernt ist?

Randolf Richardson
quelle
Für alle 3 Ansätze ist die Länge des Seils einer der Parameter, die ich zur Berechnung der Schwunggeschwindigkeit verwendet habe. Aber ich kann nicht garantieren, dass ich es richtig verwendet habe. Ich habe gerade einige physikalische Berechnungen durchgeführt und ihre gelöste Version auf das Spiel angewendet.
Ali1S232
Je weiter von der Mitte entfernt, desto länger ist die Verzögerung vor der nächsten Bewegung des Seilschwungs. Sie können den ABSolute-Wert der Verzögerung auch mit etwa 0,28 multiplizieren (Sie müssen damit experimentieren).
Randolf Richardson
Ich kann nicht verstehen, was Sie sagen wollen. Wenn ich den nächsten Schritt berechne, habe ich einen konstanten Wert für delta_time und verwende alle Parameter, die ich habe (wie die vorherige Geschwindigkeit, die vorherige Position, die Seillänge usw.), um zu berechnen neue Geschwindigkeit, und addieren Sie dann diese Geschwindigkeit multipliziert mit delta_time zur letzten Position, um eine neue Position zu generieren. Wenn Sie etwas anderes meinen, geben Sie bitte in Ihrer Antwort alle Details an.
Ali1S232
1

Wenn der Spieler weiter als die Länge des Seils ist, wird der Spieler sofort mit einer Kraft zurückgeschoben, die der Entfernung entspricht, die er passiert hat. Dies sollte funktionieren, ohne sich federnd zu fühlen, und sollte sich für den Spieler intuitiv anfühlen. Möglicherweise müssen Sie Ihre Physik optimieren, um die besten Ergebnisse für Ihr Spiel zu erzielen.

Wenn das Seil befestigt ist. Speichern Sie einen maxLengthWert.

Überprüfen Sie bei jedem Update das distancezwischen dem playerund demattachPoint

Wenn das distanceweniger als das maxLengthUpdate normalerweise ist, keine Auswirkungen von Seil.

Wenn der Abstand größer als der ist maxLength, suchen Sie den normalvom attachPointzum Spieler. Holen Sie sich den Unterschied zwischen distanceund maxLength. Addiere zu playerVelocity, normalmultipliziert mit der Differenz.

Pseudocode:

dx = (attachPoint.x - player.x)
dy = (attachPoint.y - player.y)

distance = sqrt(dx*dx+dy*dy);

if (distance > maxDistance)
{
    float dx1 = dx / distance * maxDistance;
    float dy1 = dy / distance * maxDistance;
    v.x += (dx1 - dx) / dt;
    v.y += (dy1 - dy) / dt;
}

playerVel += v * dt;
AttackingHobo
quelle
Ist der Code, den ich in Ihrer Antwort bearbeitet habe (Entschuldigung, aber ich habe keinen besseren Ort gefunden, um ihn hinzuzufügen), der von Ihnen vorgeschlagene?
Ali1S232
Ich habe der Bearbeitung zugestimmt, und ja, ich denke, das sollte es sein. Obwohl ich vorher die Seilphysik verwendet habe und eine viel kompliziertere Methode verwendet habe, um dasselbe zu tun, bin ich mir nicht ganz sicher, ob dieser Code richtig funktioniert, aber ich denke, er sollte und selbst wenn dies nicht der Fall ist, bringt er Ihnen 95 % des Weges dorthin.
AttackingHobo
Nach einigen Versuchen werde ich Box2d für dieses Problem ausprobieren und übrigens müssen Sie diesen Code so ändern, dass Sie dx = player.x - attachpoint.xund haben dy = player.y - attachpoint.y.
Ali1S232
1

Wenn Sie sich http://www.cocos2d-iphone.org/archives/1112 ansehen gibt es eine Implementierung eines Seils mit einem starren Körper, der am Ende des Seils befestigt ist. Es verwendet Box2D für die Physik-Engine. Wenn Sie sich den Quellcode ansehen, können Sie ihn sicher in einer beliebigen Sprache implementieren.

Der obige Link zur Rope-Frage gehört mir und diese Demo (Link oben) hat wirklich geholfen.

Joey Green
quelle