Timestep semi-fisso o completamente fisso?


15

Sto realizzando un iPhone shmup e sto cercando di decidere quale tipo di loop di gioco usare. Voglio usare timestep semi-fisso o timestep completamente fisso.

Con timestep semi-fisso eseguirò zero o più chiamate di aggiornamento (FIXED_INTERVAL) seguite da una chiamata di aggiornamento (dt) dove dt <= FIXED_INTERVAL per ciclo di gioco. Da quanto ho capito, gli svantaggi di questo metodo sono che la mia logica di aggiornamento fisico (dt) sarà più difficile da programmare perché in pratica devo assumere una variabile dt per ogni aggiornamento. E poi ho anche sentito che ogni serie del mio gioco sarà leggermente diversa a causa dei valori in virgola mobile che non coincidono ogni volta.

Quindi con un timestep completamente fisso sto effettuando zero o più chiamate di aggiornamento (FIXED_INTERVAL) seguite da una chiamata di interpolazione (dt / FIXED_INTERVAL) dove dt <FIXED_INTERVAL per loop di gioco.

Quindi sembra che la grande decisione che devo davvero prendere è: voglio affrontare la sfida dell'implementazione di un aggiornamento (dt) con una variabile dt o voglio affrontare la sfida dell'implementazione dell'interpolazione?

Ora, da quello che ho letto, la maggior parte delle persone dice di usare il sistema completamente fisso e di fare l'interpolazione. Ma quando penso all'implementazione dell'interpolazione sembra che sarei molto più complesso di un aggiornamento (dt) con variabile dt. Questo perché se uso l'interpolazione devo ricordare sia lo stato precedente che lo stato corrente. Quindi, se voglio usare l'interpolazione, devo escogitare un ulteriore livello di riferimento indiretto che astragga interi stati di gioco individuali. Mentre con un timestep semi-fisso in cui non devo usare l'interpolazione, non devo inventare un'astrazione dello stato del gioco perché c'è sempre solo uno stato del gioco ed è semplicemente gli "array globali" che rappresentano i miei nemici e nemici proiettili ecc.

Quindi qual è la scelta più pratica: la implemento semi-fissa sapendo che i miei aggiornamenti di fisica potrebbero complicarsi con la variabile dt. Oppure uso completamente fisso e provo a trovare un'astrazione dello stato del gioco in modo da poter tenere traccia dello stato precedente e dello stato corrente al fine di eseguire l'interpolazione?



1
Ho letto quella discussione e i collegamenti lì più volte. In realtà è come sono arrivato a questo post. La mia domanda ha principalmente a che fare con come implementare gli stati di gioco al fine di raggiungere l'interpolazione - che non è affatto coperto in quella discussione.
Ryan,

Risposte:


12

Completamente risolto

Perdi la maggior parte dei vantaggi di un timestep fisso quando lanci in un passaggio variabile una volta ogni fotogramma.

Noel Lopis ha una bella descrizione di come ha implementato una fase temporale fissa nel suo gioco Casey's Contraptions . Come bonus per te è uno sviluppatore di iPhone, anche se la sua tecnica non è specifica per iPhone.

Alcuni punti salienti dell'articolo

  • Utilizzare un accumulatore di tempo.
  • Utilizzare la frequenza fisica 120Hz per una frequenza fotogrammi 60Hz.
  • Simula un passo fisso verso il futuro e usa l'accumulo nel tempo per estrarre il codice tra lo stato fisico corrente e lo stato fisico futuro.
  • vari gotchas

2

Ciò che chiami timestep "semi-fisso" e "completamente fisso" sono, a mio avviso, entrambi timestep fissi - il dt che stai passando alla tua updatechiamata non cambia tra i frame.

Quindi, la tua domanda è in realtà "voglio implementare l'interpolazione ai fini del rendering?" La risposta è: probabilmente no .

L'interpolazione è qualcosa che vorresti fare solo se il tuo updatetimestep fisso è marcatamente diverso dal rendertimestep target . Non è insolito per i giochi che hanno una updatefase faticosa chiamare solo update, diciamo, a 10Hz, ma renderizzare a framerate completo.

Dal momento che stai scrivendo un iPhone shmup, né il tuo updatené il tuo renderbisogno sono particolarmente impegnativi per la CPU; puoi facilmente bloccare il tuo framerate a 30Hz o 60Hz, non preoccuparti dell'implementazione e avere comunque un gioco dall'aspetto fluido.


Non capisco Stai dicendo che posso bloccare il grosso dt che avrei calcolato nel mio ciclo di gioco - che la mia fisica consuma? Come lo faccio? Posso farlo con CADisplayLink? Voglio dire, quale% di CPU stai supponendo che sto usando? Dovresti davvero supporre che il game loop bloccato dt?
Ryan,

Ciò che sto dicendo si riduce davvero a questo: fare la cosa meno complicata che funzionerebbe.
Blair Holloway,

1
Elaborazione: usare una variabile dtper updateed renderè la cosa più semplice che funzionerebbe, ma generalmente evitata quando si usano i motori fisici per l'instabilità che causa. Pertanto, chiamare updatecon un numero fisso dte renderizzarlo alla stessa velocità (lasciando cadere i frame se la updatecorsa è lunga) è generalmente la cosa più semplice che funzioni. La scrittura di codice per interpolare gli oggetti tra le updatechiamate aggiunge complessità al codice; complessità che stai aggiungendo per risolvere nessun problema in particolare.
Blair Holloway,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.