Ich frage mich, wie Zeitmanipulationsmechanismen in Spielen normalerweise aufgebaut sind. Ich bin besonders an Zeitumkehr interessiert (ähnlich wie in der neuesten SSX oder Prince of Persia).
Das Spiel ist ein 2D-Top-Down-Shooter.
Der Mechanismus, den ich entwerfen / implementieren möchte, stellt die folgenden Anforderungen:
1) Aktionen von Entitäten außer dem Spielercharakter sind vollständig deterministisch.
- Die Aktion, die eine Entität ausführt, basiert auf den seit dem Start des Levels fortschreitenden Frames und / oder der Position des Spielers auf dem Bildschirm
- Entitäten werden zur festgelegten Zeit während des Levels erzeugt.
2) Die Zeitumkehr funktioniert durch Zurückkehren in Echtzeit.
- Spieleraktionen werden ebenfalls umgekehrt, es wird in umgekehrter Reihenfolge wiederholt, was der Spieler ausgeführt hat. Der Spieler hat während der Rückwärtszeit keine Kontrolle.
- Die Zeit für das Umkehren ist unbegrenzt. Auf Wunsch können wir bis zum Anfang des Levels umkehren.
Als Beispiel:
Frames 0-50: Der Spieler bewegt sich in dieser Zeit um 20 Einheiten vorwärts. Feind 1 erscheint in Frame 20. Feind 1 bewegt sich in Frame 30-40 um 10 Einheiten nach links. Der Spieler schießt eine Kugel auf Frame 45. Die Kugel bewegt sich 5 vorwärts (45-50) und tötet Feind 1 um Rahmen 50
Wenn Sie dies umkehren, wird dies in Echtzeit wiedergegeben: Der Spieler bewegt sich in dieser Zeit 20 Einheiten rückwärts. Feind 1 wird bei Bild 50 wiederbelebt. Die Kugel erscheint bei Bild 50 wieder. Die Kugel bewegt sich rückwärts 5 und verschwindet (50-45). Der Feind bewegt sich nach links. 10 (40-30) Der Feind wird bei entfernt Rahmen 20.
Als ich nur die Bewegung betrachtete, hatte ich einige Ideen, wie ich dies erreichen könnte. Ich dachte daran, eine Schnittstelle zu haben, die das Verhalten ändert, wenn die Zeit voranschreitet oder sich umkehrt. Anstatt so etwas zu tun:
void update()
{
movement += new Vector(0,5);
}
Ich würde so etwas machen:
public interface movement()
{
public void move(Vector v, Entity e);
}
public class advance() implements movement
{
public void move(Vector v, Entity e)
{
e.location += v;
}
}
public class reverse() implements movement
{
public void move(Vector v, Entity e)
{
e.location -= v;
}
}
public void update()
{
moveLogic.move(new vector(5,0));
}
Ich erkannte jedoch, dass dies in Bezug auf die Leistung nicht optimal wäre und für fortgeschrittenere Aktionen (wie z. B. sanfte Bewegungen entlang gekrümmter Pfade usw.) schnell kompliziert werden würde.