Mi chiedo come siano tipicamente progettati i meccanismi di manipolazione del tempo nei giochi. Sono particolarmente interessato all'inversione del tempo (un po 'come nell'ultimo SSX o Prince of Persia).
Il gioco è uno sparatutto top down 2D.
Il meccanismo che sto cercando di progettare / implementare ha i seguenti requisiti:
1) Le azioni di entità diverse dal personaggio del giocatore sono completamente deterministiche.
- L'azione intrapresa da un'entità si basa sui frame fatti dall'inizio del livello e / o sulla posizione del giocatore sullo schermo
- Le entità vengono generate all'ora prestabilita durante il livello.
2) Il reverse time funziona invertendo in tempo reale.
- Anche le azioni del giocatore sono invertite, ripete al contrario ciò che il giocatore ha eseguito. Il giocatore non ha controllo durante il tempo inverso.
- Non vi è alcun limite al tempo trascorso all'inversione, se lo si desidera è possibile invertire completamente l'inizio del livello.
Come esempio:
Fotogrammi 0-50: il giocatore muove in avanti di 20 unità in questo momento Il nemico 1 si genera nel frame 20 Il nemico 1 si sposta di 10 unità nel frame 30-40 Il giocatore spara proiettile nel frame 45 Il proiettile viaggia 5 in avanti (45-50) e uccide il nemico 1 in telaio 50
Inversione di questo sarebbe riprodotta in tempo reale: il giocatore si sposta indietro di 20 unità durante questo periodo. Il nemico 1 rianima al frame 50 Il proiettile riappare al frame 50 Il proiettile si sposta indietro 5 e scompare (50-45) Il nemico si sposta a sinistra 10 (40-30) Il nemico rimosso a telaio 20.
Solo guardando il movimento avevo alcune idee su come raggiungere questo obiettivo, ho pensato di avere un'interfaccia che ha cambiato il comportamento per quando il tempo stava avanzando o invertendo. Invece di fare qualcosa del genere:
void update()
{
movement += new Vector(0,5);
}
Vorrei fare qualcosa del genere:
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));
}
Tuttavia mi sono reso conto che questo non sarebbe stato ottimale per le prestazioni e sarebbe diventato rapidamente complicato per azioni più avanzate (come movimenti fluidi lungo percorsi curvi ecc.).