Richtige Reihenfolge der Operationen in einer Platformer-Spielschleife

7

Ich bin auf ein Problem mit meiner Mega Man-Engine gestoßen, und die Struktur meiner Spielschleife macht es sehr schwierig, sie zu beheben. Bei Rush Jet oder einer fallenden Plattform muss Mega Man beim Fallen an der Plattform hängen bleiben. Das Beste, was ich tun kann (ohne auf Problemumgehungen wie magische Kraftfelder zurückzugreifen, die ihn nach unten ziehen), ist, dass er für einen einzelnen Frame fällt, wenn die Plattform zum ersten Mal zu fallen beginnt. Aber selbst dies erfordert, dass die fallende Plattform ihn während der Kollisionsprüfung nach unten zieht. Ohne diesen zusätzlichen Schritt "zittert" er ständig beim Fallen, wenn die Plattform absteigt.

Die Reihenfolge der Ereignisse in meiner Spielschleife macht dies möglich. Es geht so:

  1. Mega Man und Rush Jet fliegen eine Weile horizontal.
  2. Denkphase: Spieler drückt nach unten - die Plattform beschließt, ihre Geschwindigkeit nach unten zu setzen.
  3. Aktionsphase: Die Plattform bewegt sich nach unten, der Spieler ist sich dessen nicht bewusst.
  4. Reaktionsphase: Die beiden kollidieren nicht, so dass keine Überprüfung der "Bindungskraft" stattfinden kann.
  5. Im nächsten Frame fällt Mega Man. Einen Frame später holt die Schwerkraft auf und er landet wieder auf der Plattform und setzt seine y-Geschwindigkeit auf 0 zurück.

Sie können dort die Grundreihenfolge meiner Schleife sehen:

  1. Denkphase, in der Sie Kollisionen aus dem vorherigen Frame und andere Variablen analysieren, um über Zustandsübergänge und andere Anpassungen zu entscheiden.
  2. Aktionsphase - Jeder bewegt sich entsprechend seiner Geschwindigkeit.
  3. Reaktionsphase - Kollisionsprüfungen, Positionen anpassen, um sie zu fixieren. Dies behandelt auch Effekte wie das Verschieben von Plattformen, z. Schieben Sie den Spieler um einen gewissen Betrag. Die Änderungen seiner Geschwindigkeit werden im nächsten Frame während der Aktionsphase angewendet.

Ich habe versucht, diese Schritte und verschiedene andere Änderungen neu zu ordnen, aber sie alle machen das Ganze noch schlimmer, mit allen möglichen Fehlern. Wenn ich umfassende Änderungen an meinem Motor vornehmen muss, um diese Dinge richtig zu machen, möchte ich lieber wissen, was der "richtige" Weg ist, bevor ich Zeit verschwende.

Ich weiß, dass eine mögliche Lösung darin besteht, im Bewegungsschritt zu sehen, wer die Plattform im vorherigen Bild berührt hat, und ihn dann zu ziehen, damit sie sich tatsächlich zusammen bewegen. Das scheint jedoch zu komplex, um zwischen solchen Komponenten zu greifen. Mein Engine-Code fühlt sich bereits viel komplizierter an, als es das ursprüngliche Spiel hätte sein können, was darauf hindeutet, dass ich etwas falsch mache.

Gibt es also eine richtige Abfolge von Ereignissen? Es gibt hier eine andere Frage zum Verschieben von Dingen zusammen mit einer Plattform, die jedoch nicht die Reihenfolge der Ereignisse anspricht, die mein Problem verursacht. Wenn jemand wirklich weiß, wie die klassischen Mega Man-Spiele es gemacht haben, wäre das natürlich eine große Hilfe.

Unter https://github.com/Tesserex/C--MegaMan-Engine/tree/master/Mega%20Man finden Sie so viel von meinem Code, wie Sie möchten . Die CollisionComponent und die MovementComponent sind möglicherweise am nützlichsten.

Tesserex
quelle
1
Ich verstehe das nicht ganz, aber da sich Mega Man und Plattform zusammen bewegen, wäre es vielleicht keine schreckliche Sache, ihre Bewegung zusammenzubinden. (Wenn sie sich wie eine Entität zusammen bewegen, warum programmieren Sie sie nicht als eine Entität oder binden sie zumindest auf irgendeine Weise?)
Michael Coleman
Die Art und Weise, wie ich das Problem des "Fallens nach einer Plattform" löste, bestand darin, nicht in den fallenden Zustand überzugehen, bis der Spieler mindestens zwei Frames keinen Kontakt mehr mit dem Boden hatte. Der Spieler fällt; Die Animationen ändern sich jedoch nicht, sodass der Spieler es nicht bemerkt. Dies bewältigt auch das Gehen an Hängen ziemlich gut.
Blecki
@Blecki - Das kann bei mir funktionieren oder auch nicht - mein System ist anpassbar, es wäre also eine ziemlich allgemeine Änderung. Wie auch immer, ich bin immer noch interessiert, ob jemand die "richtige" Reihenfolge der Spielschleifen kennt.
Tesserex

Antworten:

2

Ich weiß, dass diese Antwort nicht zum Titel dieser Frage passt, aber ich denke, sie könnte Ihr Problem lösen.

Ich habe mir Ihre Codebasis angesehen und Sie haben ein aggregiertes Komponentendesign zum Erstellen von Spielentitäten. Ich vermute, der Rush Jet hat eine eigene Spieleinheit und eine Liste von Komponenten ("Rush Jet" nenne ich diese bewegliche Plattform, ja, ich weiß nichts über Mega-Man-Spiele). Wenn dies der Fall ist, sollten Sie versuchen, den Rush Jet einer Spieler-Spieleinheit zu übergeben und eine Art Brücke einzurichten (nicht der beste Begriff).

Für diese "Brücke" hätte ich den Rush Jet nicht über die Tastatur eingegeben. Stattdessen würde der Spieler Eingaben vornehmen und in Ihrem Nachrichtensystem (das für die Spielkomponenten in einer Entität) könnte eine andere Spielkomponente an den Rush Jet gebunden sein, die auch die Bewegungsnachricht abfängt. Somit würden sowohl der Spieler als auch die Plattform zusammen bewegt. Sobald der Rushjet verschwunden ist, wird die Spielkomponente, die als Brücke zwischen dem Rushjet und dem Spieler dient, entsorgt und entfernt.

Ich denke, das ist eine plausible Alternative. Die Bewegung findet in Ihrer Spielschleife statt, und dann werden die Kollisionsprüfungen durchgeführt, um sicherzustellen, dass sich der Rush Jet und der Spieler innerhalb der Grenzen befinden. Ich glaube auch, dass es vollkommen in Ordnung ist, wenn der Rush-Jet auf diese Weise vom Spieler abhängig ist. Es ist nicht die großartigste Lösung, aber es wird wahrscheinlich funktionieren.

PS: Ich mag deine Codebasis. Der Code ist nicht der beste, aber es ist schön.

Michael Coleman
quelle
Vielen Dank. Ich denke, das ist ein neuartiger Ansatz. Die Spielentitäten werden extern definiert, und der Hauptgrund, warum ich wollte, dass es ohne irgendeine spezielle Verbindung zwischen ihnen funktioniert, ist, dass andere fallende Plattformen nicht die gleiche spezielle Behandlung benötigen, um zu funktionieren. Aber vielleicht kann ich diesen Ansatz verwenden, um die Erstellung solcher Plattformen zu vereinfachen.
Tesserex
Das einzige, was die Plattform und den Player verbindet, ist eine Entitätskomponente. Auf diese Weise können Sie andere Plattformen erstellen und diese Entitätskomponente nicht an den Player anhängen. Sie lassen die Plattform für Erweiterungen offen, was es einfacher macht.
Michael Coleman
Nun, so wie ich es bisher zum Laufen gebracht habe, habe ich eine Hitbox verwendet, um zwischen den beiden zu kommunizieren. Im Moment scheint es also keine einfache Lösung zu geben, die nicht jeweils mindestens ein kleines anderes Objekt erzeugt.
Tesserex
Ja, aber ist dieses kleine Objekt wirklich ein Problem? Es wird nur einmal während eines Frames zugewiesen. Sehr kleine Menge meiner Meinung nach.
Michael Coleman
Richtig, es funktioniert gut. Sie müssen sich nur jedes Mal daran erinnern, wenn Sie eine solche Plattform erstellen.
Tesserex
0

Okay, in seiner einfachsten Form sieht eine Spielschleife so aus:

while game is running
    act upon user input
    update all game objects
    re-draw everything to the screen

In Ihrem Fall sollte Folgendes passieren:

  1. Die Schleife beginnt.
  2. Sie aktualisieren alle Objekte basierend auf den Tastendrücken, die stattgefunden haben. Plattform bewegt sich nach unten.
  3. Anschließend aktualisieren Sie alle Objekte basierend auf ihren Geschwindigkeiten. In diesem Schritt sollte eine Kollisionsprüfung durchgeführt werden, um nicht die gesamte Entfernung zu erreichen oder ihre Geschwindigkeiten auf Null zu ändern, wenn sie gegen Wände stoßen (durch Wände gehen) und sie an den richtigen Stellen platzieren.
  4. Zeichnen Sie nun alles auf den Bildschirm. Der Benutzer hat noch nie einen Fehlerzustand gesehen, sodass alles gut aussieht. Keine Nervosität jemals.

Und so funktionieren die meisten Spiele, die ich schreibe.

Update: Wenn Sie weitere Informationen zum Schreiben einer guten Spieleschleife benötigen, lesen Sie jetzt weiter als diese gute Anleitung .

Robert Massaioli
quelle
In diesem Artikel geht es anscheinend ausschließlich darum, wie die Spielschleifenzeit mit der Hardwaregeschwindigkeit korrekt eingestellt werden kann. Aber Ihr Vorschlag scheint darauf hinzudeuten, dass meine Bestellung korrekt ist. So wie Sie es haben, würde das Problem meiner Meinung nach immer noch bestehen. Ich denke, ich muss eine Art Magie machen, die die beiden zusammenhält.
Tesserex
@ Tesserex: Ich verstehe nicht; Wenn Sie die Position der Plattform ändern, bevor der Spieler seine Schwerkraftprüfung durchführt, bewegt er sich dann nicht nach unten und verbindet sich mit der Plattform, bevor der nächste Schritt erfolgt ist? Ohne auf Ihren Code zu schauen, scheint es nur, dass Sie ein Problem mit der Reihenfolge der Operationen haben, daher mein Beitrag.
Robert Massaioli