Ich habe noch nie wirklich viel Spielprogrammierung gemacht, ziemlich unkomplizierte Frage.
Stellen Sie sich vor, ich baue ein Tetris-Spiel, dessen Hauptschleife ungefähr so aussieht.
for every frame
handle input
if it's time to make the current block move down a row
if we can move the block
move the block
else
remove all complete rows
move rows down so there are no gaps
if we can spawn a new block
spawn a new current block
else
game over
Bisher geschieht alles im Spiel sofort - Dinge werden sofort erzeugt, Zeilen werden sofort entfernt usw. Aber was ist, wenn ich nicht möchte, dass Dinge sofort geschehen (dh Dinge animieren)?
for every frame
handle input
if it's time to make the current block move down a row
if we can move the block
move the block
else
?? animate complete rows disappearing (somehow, wait over multiple frames until the animation is done)
?? animate rows moving downwards (and again, wait over multiple frames)
if we can spawn a new block
spawn a new current block
else
game over
In meinem Pong-Klon war dies kein Problem, da ich in jedem Frame nur den Ball bewegte und nach Kollisionen suchte.
Wie kann ich mich um dieses Problem kümmern? Sicherlich beinhalten die meisten Spiele eine Aktion, die mehr als einen Frame benötigt, und andere Dinge werden angehalten, bis die Aktion abgeschlossen ist.
Action
Klasse und eine Reihe von Aktionen vor, die ausgeführt werden sollen. Wenn eine Aktion abgeschlossen ist, entfernen Sie sie aus der Warteschlange und führen Sie die nächste Aktion usw. aus.Ich übernehme dies aus Game Coding Complete von Mike McShaffry.
Er spricht von einem „Prozessmanager“, der sich auf eine Liste von Aufgaben beschränkt, die erledigt werden müssen. Beispielsweise würde ein Prozess die Animation zum Zeichnen eines Schwertes (AnimProcess) oder zum Öffnen einer Tür steuern oder in Ihrem Fall die Zeile verschwinden lassen.
Der Prozess wird zur Liste des Prozessmanagers hinzugefügt, die bei jedem Frame und jedem aufgerufenen Update () iteriert wird. Also sehr ähnliche Entitäten, aber für Aktionen. Es gibt ein Kill-Flag, das aus der Liste entfernt werden muss, wenn es beendet ist.
Das andere nette an ihnen ist, wie sie sich verbinden können, indem sie einen Zeiger auf den nächsten Prozess haben. Auf diese Weise kann Ihr animierter Zeilenprozess tatsächlich bestehen aus:
(Da Prozesse Dinge sein können, die nur einmal verwendet werden können, bedingt dort oder für eine bestimmte Zeitspanne)
Wenn Sie weitere Informationen wünschen, wenden Sie sich an uns.
quelle
Sie können eine Prioritätswarteschlange von Aktionen verwenden. Sie drücken eine Aktion und eine Zeit ein. In jedem Frame erhalten Sie die Zeit, und Sie entfernen alle Aktionen, für die eine Zeit angegeben wurde, und führen sie aus. Bonus: Der Ansatz verläuft gut parallel und Sie können praktisch die gesamte Spiellogik auf diese Weise implementieren.
quelle
Sie müssen immer den Zeitunterschied zwischen dem vorherigen und dem aktuellen Frame kennen, dann müssen Sie zwei Dinge tun.
-Entscheiden Sie, wann Sie Ihr Modell aktualisieren möchten: z. Wenn in Tetris eine Zeilenentfernung beginnt, möchten Sie nicht, dass Inhalte mehr mit der Zeile kollidieren. Entfernen Sie daher die Zeile aus dem 'Modell' Ihrer Anwendung.
-Sie müssen dann das Objekt, das sich in einem Übergangszustand befindet, in eine separate Klasse umwandeln, die die Animation / das Ereignis über einen bestimmten Zeitraum auflöst. Im Tetris-Beispiel müsste die Zeile langsam ausgeblendet werden (ändern Sie die Opazität für jedes Bild ein wenig). Nachdem die Undurchsichtigkeit 0 ist, werden alle Blöcke oben in der Reihe um eins nach unten verschoben.
Dies mag auf den ersten Blick etwas kompliziert erscheinen, aber Sie werden den Dreh rausfinden. Stellen Sie einfach sicher, dass Sie in verschiedenen Klassen viel abstrahieren. Dies wird es einfacher machen. Stellen Sie außerdem sicher, dass zeitaufwändige Ereignisse wie das Entfernen einer Zeile in Tetris vom Typ "Fire and Forget" (Feuer und Vergessen) sind. Erstellen Sie einfach ein neues Objekt, das alles behandelt, was automatisch erledigt werden muss, und das, wenn alles erledigt ist. Entfernt sich von Ihrem Szenenbild.
quelle
Sie müssen sich das Spiel als "endliche Zustandsmaschine" vorstellen. Das Spiel kann sich in einem von mehreren Zuständen befinden: in Ihrem Fall "Eingabe erwarten", "Teil nach unten bewegen", "Reihe explodieren".
Sie tun je nach Bundesstaat unterschiedliche Dinge. Beispielsweise ignorieren Sie während des "Abwärtsfahrens" die Eingaben des Spielers und animieren stattdessen das Stück von seiner aktuellen Reihe in die nächste Reihe. Etwas wie das:
quelle