Ich habe mich gefragt, wie ich Zeitreisen in ein Spiel implementieren kann. Nichts Superkomplexes, nur Zeitumkehr wie in Braid, wo der Benutzer die Zeit um 30 Sekunden zurückspulen / vorspulen kann oder was auch immer.
Ich habe viel im Internet gesucht, aber meine Ergebnisse bezogen sich normalerweise auf die Verwendung von Zeit wie "es ist 3:00" oder einen Timer und so weiter.
Das einzige, was ich mir vorstellen konnte, war, zwei Arrays zu verwenden, eines für die x-Position des Spielers und das andere für die y-Position des Spielers, und dann diese Arrays zu durchlaufen und den Charakter an dieser Position zu platzieren, während er zurückspult / schnell vorspult. Könnte das funktionieren? Wenn es funktionieren würde, wie groß müsste das Array sein und wie oft sollte ich das x und y des Players speichern? Was könnte ich sonst noch versuchen, wenn es nicht funktioniert?
Danke im Voraus!
quelle
import universal.back2future.FluxCapacitor;
Antworten:
Die Array-Idee ist ziemlich genau so, wie sie in Braid implementiert wurde. Wenn die einzigen Dinge, die auf einen Charakter einwirken, die Schwerkraft, die Tastatur- / Joypad-Eingabe und andere Charaktere sind, müssen Sie so ziemlich nur die Position und die Geschwindigkeit bei jedem Schritt speichern, um alles Wichtige über diesen Charakter zu wissen. Wenn Sie 10 Schnappschüsse pro Sekunde und Charakter speichern, sind es für eine Minute des Verlaufs eines Charakters immer noch weniger als 50.000 - auf den meisten Systemen leicht zu verwalten, und Sie können auch effizientere Wege finden.
quelle
Informieren Sie sich über das Befehlsmuster . Es sieht vor, Aktionen rückgängig zu machen (und sie später erneut auszuführen). Dies würde mehr als nur die Position eines Schiffes behandeln, sondern alle Aktionen, die der Spieler ausführt.
Aber ich denke, Ihre Array-Idee ist auch solide.
quelle
(x+v)-v
möglicherweise nicht gleichx
.Anstatt zwei separate Arrays zu haben, sollten Sie wahrscheinlich eine Klasse haben, die die Position des Spielers beschreibt (es gibt wahrscheinlich bereits eine Point-Klasse in Java ... Ich bin in letzter Zeit ein C # -Typ) und ein einziges Array verwenden, um vergangene Positionen zu halten.
Sie müssen einen "Ringpuffer" einrichten, dh, wenn Sie am Ende des Arrays angelangt sind, kehren Sie zum Anfang des Arrays zurück und überschreiben die ältesten Einträge. Wenn Sie in der Zeit zurückreisen, ist das Gegenteil der Fall (wenn Sie am Anfang angelangt sind, kreisen Sie bis zum Ende ein).
Wenn Sie vergangene Daten im Wert von 30 Sekunden speichern möchten, müssen Sie Ihre Bildrate kennen, wenn Sie Speicherplatz vorab zuweisen und ein Array mit fester Größe verwenden möchten. Wenn Sie das Spiel mit 10 Bildern / Sekunde und 30 Sekunden rendern, sind das 300 Elemente.
quelle
GDCVault hat einen Vortrag von Jon Blow (dem Schöpfer von Braid ) auf seiner Website mit dem Titel The Implementation of Rewind in Braid für 3,95 US-Dollar. Ich wette, das hat die Infos, die du willst;)
EDIT: Wird wahrscheinlich nicht in Java sein, aber die Ideen sollten halten.
quelle
Wie Erik J sagte , klingt es vernünftig, die früheren Positionen des Spielers als Sammlung von Punktobjekten in einem Ringpuffer zu speichern.
Ich würde jedoch vorschlagen, eine Warteschlange zum Implementieren des Puffers zu verwenden. Das Aktualisieren ist viel billiger als ein Array, und Sie müssen Ihre Bildrate nicht im Voraus kennen:
Dies berücksichtigt noch keine unterschiedlichen Bildraten oder was passieren sollte, wenn Sie tatsächlich Zeitreisen unternehmen. Ich empfehle daher, bei jedem Eintrag einen Zeitstempel zu speichern und stattdessen Folgendes zu überprüfen:
Hoffe das hilft!
quelle
Es gibt ein Designmuster namens Memento , ich denke, es ist ein Ausgangspunkt für ein Spiel wie Braid
http://en.wikipedia.org/wiki/Memento_pattern
Weitere Informationen hier: http://dofactory.com/Patterns/PatternMemento.aspx
quelle
Für die XBox360 wurde ein Spiel veröffentlicht, das Zeitmanipulationen beinhaltete. Es war mittelmäßig, daher kann ich mich derzeit nicht an den Titel erinnern. Wie auch immer, in einem Interview mit einem Entwickler haben sie dargelegt, wie sie mit Zeitmanipulation umgegangen sind:
In jedem X-Frame (mit niedrigeren X-Werten, die zu einer feinkörnigeren Manipulation führen) erstellen Sie zu diesem Zeitpunkt einen "Schnappschuss" der Spielwelt und verknüpfen ihn mit einer Zeit im Spiel.
Während Sie das Spiel normal und zeitlich vorwärts durchspielen, trägt jede Eingabe und Reaktion zu einem späteren Zeitpunkt zum Schnappschuss bei.
Die Spielwelt iteriert dann zwischen dem aktuellen Snapshot und den zukünftigen Snapshot-X-Frames.
Wenn Sie dann die Zeit umkehren möchten, stellen Sie einfach die Zeitrichtung so ein, dass sie rückwärts ist, sodass sie in der Vergangenheit zwischen dem aktuellen und dem Snapshot-X-Frame iteriert (während die Möglichkeit deaktiviert wird, zukünftige Snapshots zu erstellen).
quelle
Sie können die virtuelle Zeit des Spiels einfach als eine andere raumähnliche Dimension behandeln. Was also Zeitreisen von außen sind, ist eine einfache n + 1-dimensionale Bewegung im virtuellen Universum des Spiels.
Unter der Annahme einer Benutzerinteraktion und einer Art Physiksystem, das das Verhalten Ihres Universums bestimmt, wenn keine Benutzereingaben vorliegen, müssen Sie lediglich den Effekt von Benutzerinteraktionen aufzeichnen (z. B. Änderungen der Geschwindigkeits- / Beschleunigungsvektoren der Dimension n + 1). , da Ihre Physik zeitlich reversibel sein sollte.
Auf diese Weise benötigen Sie viel weniger Speicher, um den Status des Spieluniversums zu einem bestimmten Zeitpunkt zu berechnen.
quelle
(x+v)-v
x
Angenommen, eine Entität hat eine Geschwindigkeits-, Rotations-, x- und y-Position. Dies sind mit Beschleunigung die grundlegenden Bewegungszustände, Werte, wie auch immer Sie es nennen. Sie können die Daten auf zwei Arten
speichern : 1. Speichern Sie Rotation, x- und y-Position.
2. Speichern Sie Rotation, x-Geschwindigkeit und y-Geschwindigkeit
Wenn Sie eine feste Geschwindigkeit haben, können Sie auch nur die Drehung oder nur eine Geschwindigkeit für beide Achsen speichern.
Das Speichern der Rotation ist in Spielen erforderlich, es sei denn, Ihre Entität verfügt über eine statische Rotation, was in den meisten Fällen nicht der Fall ist.
Die Verwendung einer Liste von Objekten für mehrere Werte ist jedoch erforderlich. Wenn Sie ein nettes Timer-System haben, das beispielsweise 20 Mal pro Sekunde Aktualisierungsmethoden aufruft und daher fps-unabhängig ist, können Sie ein Array von 20 * 30 Objekten erstellen, um die Bewegungswerte zu speichern, die Sie für die letzten 30 Sekunden benötigen . Die Verwendung eines einfachen Arrays wird nicht empfohlen, da Sie jedes Element um einen Index verschieben müssten, der bei jedem Aktualisierungsaufruf übrig bleibt.
Auf dieser Grundlage können Sie die Liste oder was auch immer durchgehen, um zurück zu gehen. Wenn Sie wirklich einen "realistischen" Effekt erzielen möchten, verwenden Sie diese Technik für alle sich bewegenden Objekte. Aber das hängt mit dem Spieldesign zusammen.
Wenn Sie Objekte zerstören, denken Sie daran, diese zu bündeln, um sicherzustellen, dass Sie Ihren netten Freund Mr. Garbage nicht belasten;)
quelle