Wie gehe ich mit der Physik beweglicher Plattformen in einem Plattformer um?

8

Nach ein paar Stunden Suche im Internet habe ich noch keine erfreuliche Antwort auf den Umgang mit sich bewegenden Plattformen in einem 2D-Plattformspiel gefunden. Deshalb habe ich mich für einen einfachen Prototyp entschieden, bei dem Sie mit zwei verschiedenen Plattformen interagieren, von denen sich eine vertikal und eine horizontal bewegt. Ich würde gerne Hilfe bekommen, um zu sezieren und zu sehen, was nicht funktioniert und wie man sie repariert. Ich habe die .fla-Datei + .as-Datei unten eingereicht, zusammen mit einem Link zur abspielbaren .swf.

Das Ziel ist es, den Helden dazu zu bringen, mit den Plattformen zu interagieren, als wären sie feste Objekte, auf denen er stehen, neben die er geschoben, auf / unter usw. springen kann.

Die Probleme mit meinem Prototyp sind folgende:

  • Wenn Sie auf der sich horizontal bewegenden Plattform stehen, ohne sich zu bewegen (ohne Tasten zu berühren), bewegt sich der Held mit der Plattform mit, jedoch mit einer leichten Verzögerung, wodurch der Held ein wenig zurückgleitet.

  • Wenn Sie auf der sich horizontal bewegenden Plattform stehen und springen, bewegen Sie sich mit der Plattform in der Luft (einige Spiele bevorzugen dies, aber es fühlt sich nicht natürlich an und wird hier nicht gewünscht). Dies könnte dadurch verursacht werden, dass der Held die Geschwindigkeit auf der X-Achse von der Plattform beibehält.

  • Wenn Sie auf der sich vertikal bewegenden Plattform nach unten springen, während sich die Plattform nach unten bewegt, sinken Sie für eine kurze Sekunde darin ein. Der Held dringt durch, als ob die Kollision für einen Moment nicht existierte.

  • Wenn Sie auf eine sich vertikal bewegende Plattform springen, bleibt die Geschwindigkeit auf der Y-Achse erhalten. Wenn Sie also von der Plattform gehen, fallen Sie mit einer höheren Geschwindigkeit herunter. Mit der Geschwindigkeit der beibehaltenen Geschwindigkeit + der hinzugefügten Schwerkraft (dies liegt hauptsächlich daran, dass ich keine Möglichkeit finden kann, die Geschwindigkeit auf der Y-Achse auf 0 zurückzusetzen, wenn Sie auf der Plattform landen, ohne dass der Spieler in der Luft friert).

Ich bin ein unerfahrener Programmierer, daher bin ich mir sicher, dass es BESSERE Möglichkeiten gibt, dies zu tun, und ich würde sie gerne alle hören. Alle Ideen zur Verbesserung des Codes oder anderer Methoden, mit denen Sie bewegliche Plattformen in ein Tile-basiertes Spiel implementieren können, sind willkommen. Am Ende versuche ich, einen soliden Weg zu finden, um mit sich bewegenden Plattformen in 2D-Plattformern umzugehen.

Spielbares SWF: http://dl.dropbox.com/u/28271061/PlatformerhowtoFLA.html (Mit Pfeiltasten bewegen, Mit X-Taste springen, Mit Z-Taste ausführen)

Quellcode AS-Datei: http://dl.dropbox.com/u/28271061/Platformerhowto.as

SourcefileFLA: http://dl.dropbox.com/u/28271061/PlatformerhowtoFLA.fla

Wenn Sie den Code lieber online über Pastie lesen möchten: http://pastie.org/2266764

Kind
quelle
Relevant (unwahrscheinlich doppelt): Wie gehe ich mit sich bewegenden Plattformen in einem Plattformspiel um? .
Doppelgreener
Ich habe diesen Thread gelesen, aber da ich in keiner Weise Knoten verwende, scheint das Problem dadurch nicht gelöst zu werden. Das Spiel, das ich baue, basiert auf Kacheln, aber die beweglichen Plattformen werden wie oben implementiert (frei beweglich). Die Verwendung von Knoten würde ein Umschreiben meiner gesamten Engine erfordern, für das ich bereits lange Zeit aufgewendet habe. Ich hatte gehofft, jemand würde sich den Code ansehen und eine Lösung anbieten, die der vorgeschlagenen ähnelt, oder eine Verbesserung des Codes finden.
Kid
Sie würden Knoten verwenden, sobald Sie diese Lösung für das Verschieben von Plattformen implementiert haben, selbst wenn dies der einzige Ort ist, an dem Sie sie verwenden. Es würde Ihr Gleitproblem lösen.
Doppelgreener
2
"(Einige Spiele bevorzugen es so, aber es fühlt sich nicht natürlich an und wird hier nicht gewünscht.)" Wie fühlt es sich nicht "natürlich an"? Google Inertia and Momentum ...
Riki
1
@Felheart, Natürlich in Bezug auf das Gameplay, keine reale physische Welt. Wenn Sie Super Mario Bros oder einen der klassischen Plattformer spielen, werden Sie feststellen, dass diese beim Springen auf sich bewegenden Plattformen NICHT den Schwung bewahren. Es stört das Gefühl, mit einer sich bewegenden Plattform zu stehen und zu interagieren.
Kid

Antworten:

17

Lassen Sie uns Ihr Problem in verschiedene Themen unterteilen ...

Ein Wort zur Codequalität

In Ihrem Code steuern Ihre Plattformen derzeit direkt die Geschwindigkeit Ihres Spielers und sogar die Schwerkraftkonstante der Welt . Es ist hackig und prozedural, wenn es objektorientiert sein soll. Sobald Sie anfangen, dieses Spiel zu erweitern, werden die Dinge schnell hässlich .

Sie müssen Ihren Code umgestalten. Implementieren Sie eine Spielerklasse, eine Plattformklasse und eine Bodenklasse. Trennen Sie ihre Bedenken: Lassen Sie den Spieler die Tastatursteuerung interpretieren und steuern, wie er läuft und springt, und lassen Sie die Plattformen seinen Schwung nach Bedarf ändern (indem Sie bei Bedarf ihre eigene Geschwindigkeit zur bereits festgelegten Geschwindigkeit des Spielers hinzufügen).

Lassen Sie Ihren Spieler bestimmen, wo es sich in Bezug auf ein bodenartiges Objekt befindet (Plattformen und Böden hätten beide ein BodyType = BodyTypes.Flooroder etwas) und selbst bestimmen, wo es sich in Bezug auf das Objekt befindet, wie es reagieren soll und ob es fällt oder nicht auf dem Boden.

Dies verdient möglicherweise ein separates Thema, da es sich um ein ganz anderes Thema handelt als alles, was Sie angesprochen haben. Sie müssen es jedoch irgendwann tun.

Horizontale / vertikale Trägheit beim Verlassen einer Plattform

Beachten Sie zwei Dinge, um Ihre vertikalen und horizontalen Geschwindigkeitsprobleme zu lösen:

  • In Bezug auf die horizontale Geschwindigkeit: Ihr Code setzt die horizontale Geschwindigkeit nur auf 0, wenn der Spieler den Boden (auf der Pastie-Linie 200) oder eine Plattform berührt.
  • In Bezug auf die vertikale Geschwindigkeit: Ihr Spieler hat eine konstant fallende Beschleunigung. Wenn er die vertikale Plattform verlässt, wird diese fallende Beschleunigung immer wieder zu seiner bereits abwärts gerichteten Bewegung hinzugefügt.

Ihr Spieler leidet einfach unter Trägheit : Sein Schwung bleibt erhalten, bis etwas ihn aufhält.

Lösung: Beide Probleme durch gelöst werden würden Lösung des jSepia zu Wie gehe ich mit Plattformen in einem Plattform - Spiel zu verschieben? Dies würde den Bewegungsprozess des Spielers vollständig von der Bewegung der Plattformen trennen . Sie würden einfach nicht schneller fallen, wenn Sie von einer vertikalen Plattform gehen, und Ihren horizontalen Schwung, der von einer horizontalen Plattform springt, nicht beibehalten, da die Plattformen die vx und vy Ihres Spielers nicht mehr beeinflussen .

Hinweis: Möglicherweise haben Sie Schwierigkeiten, die jSepia-Lösung zu implementieren, bevor Ihr Code überarbeitet wird.

Gleiten von Seite zu Seite um die horizontale Plattform

Ihr Player bewegt sich horizontal nicht so schnell wie die Plattform. Mir ist nicht klar warum. Dieses Problem würde auch wahrscheinlich durch die Implementierung jSepia-Lösung gelöst werden und den Code richtig Refactoring (letzteres würde einfach die Ursache offensichtlich machen).

Kollisionserkennung: Überlappung mit der vertikalen Plattform

Siehe Pastie-Zeile 381: Bei jedem Schritt wird das vy des Spielers auf 0 zurückgesetzt, solange der Spieler mit der Unterseite der vertikalen Plattform kollidiert. Im folgenden Schritt wird vy durch die Schwerkraftbeschleunigung erhöht und dann der Spieler bewegt (und dann wieder auf 0 zurückgesetzt).

Dies bedeutet, solange Ihr Spieler mit dem Boden der Plattform kollidiert, bewegt er sich mit einer konstanten Geschwindigkeit (der Schwerkraftkonstante) nach unten. Die vertikale Plattform ist schneller als diese und überlappt ihn. Wenn sich die vertikale Plattform über eine längere Strecke bewegte, rutschte sie direkt durch ihn hindurch, bis der Spieler als auf der Plattform stehend registriert wurde.

Lösung: Setzen Sie den vy des Spielers nicht auf 0 zurück. Stellen Sie den vy des Spielers einfach auf die vertikale Geschwindigkeit der Plattform ein ( wenn die Plattform nach unten fährt ). Ihr Spieler bewegt sich dann mindestens so schnell wie die Plattform von der vertikalen Plattform weg und beschleunigt von dieser weg.

Doppelgrün
quelle
Ausgezeichnet! Zunächst einmal vielen Dank für die Lösung zum Springen und Eindringen in die vertikale Plattform (funktioniert!). Und zweitens haben Sie Recht, der Code ist in diesem Zustand schrecklich. Obwohl dies nicht das Spiel an sich ist, ist dies ein schneller Prototyp, der entwickelt wurde, um bewegliche Plattformen besser zu experimentieren und zu verstehen. Wenn ich dies jedoch in den eigentlichen Spielcode übersetzen möchte, sollte ich einen strukturierteren und objektorientierteren Code beibehalten. Dadurch wird die Übertragung geglättet. In Bezug auf die jSpeias-Lösung glaube ich, dass ich das Node-Tree-Konzept verstehe. Ich weiß nur nicht, wie ich es richtig implementieren soll.
Kid
Mein erster Gedanke ist, boolesche Werte zu erstellen, die den Status des Spielers beschreiben, wie z. B. "onFloor", "onPlatform", "onGround", "fallend", "springend" usw. enterFrame-Ereignis, das den aktuellen Status überprüft und die Spielereigenschaften entsprechend ändert (?) Beispiel: if (Hero.onPlatform == true) {Player.x = platform.x (relativ zum globalen x des Spielers);}. Etwas auf diese Weise.
Kid
Ich arbeite gerade daran, aber gleichzeitig teile ich den Code in verschiedene Klassen auf, wie Sie vorgeschlagen haben, was ebenfalls etwas verwirrend ist (die Kommunikation zwischen Plattform- / Kollisions- / Spielerklassen ist umwerfend).
Kid
@Kid: Playerhat eine Methode GetPositionund interne Variablen parent(für den übergeordneten Knoten) und position(für die Position relativ zum übergeordneten Knoten ). Player.GetPosition()kehrt zurück position + parent.GetPosition(). Das übergeordnete Element macht dasselbe, bis Sie die Wurzel des Baums erreichen - den Weltknoten. Wenn sich Ihr Spieler bewegt, beschäftigen Sie sich nur mit der privaten positionVariablen. Ihr Spieler wird entsprechend dem GetPosition()Wert auf dem Spielbildschirm gezeichnet . Ich werde Sie herausfinden lassen, wie der Übergang zwischen Knoten. ;)
Doppelgreener
Eine Spielerklasse zu haben, die weiß, wie man ihre eigene Geschwindigkeit ändert, ist natürlich keine Aufrechterhaltung der Trennung von Bedenken
Andy Ray,