Domanda

Sono in procinto di creare un gioco 2D a OpenGL ES per l'iPhone.Sto chiamando il mio ciclo di gioco usando Nstimer ad un intervallo di 0,002 (60 fps) con ripetizioni impostate su 'no' (sto usando di nuovo il nstimer dalla funzione come consigliato):


-(void)gameLoop:(id)sender {
    double currTime=(double)CACurrentMediaTime();
    m_FPS_framesThisSecond++;
    float timeThisSecond=currTime-m_FPS_lastSecondStart;
    if (timeThisSecond>1.0f) {
        m_FPS=m_FPS_framesThisSecond;
        m_FPS_framesThisSecond=0;
        m_FPS_lastSecondStart=currTime;
    }

    [game update];
    [game render];

        //Continue the loop
    [NSTimer scheduledTimerWithTimeInterval:0.002 target:self selector:@selector(gameLoop:) userInfo:nil repeats:NO];
}

.

Questo funziona senza intoppi sui miei 3GS, tuttavia quando lo testo su un 2G il gioco funziona molto più lentamente e a volte ottengo i telai vuoti occasionali.Quando abbassare l'intervallo a 0,033 (30 fps).È troppo lento sul 3G.

So che ci deve essere un modo per ottenere una riproduzione costistente su entrambi i dispositivi.Doodle Jump sembra funzionare senza intoppi e allo stesso frametate su entrambi i telefoni.

È stato utile?

Soluzione

Il problema essenziale è questo:

Il tuo gioco deve aggiornarsi in base alla quantità di tempo che è passato dall'ultima volta che ha reso, non da quante volte ha reso. Supponiamo che tu stia calcolando la posizione di uno sprite in base a qualche velocità. La nuova posizione dovrebbe essere calcolata in base al tempo tra i rendering, non con l'assunto 0,002 secondi è passato dall'ultimo rendering. Questa è chiamata animazione indipendente FPS.

Quindi, ecco un semplice esempio:

// FPS dependent animation
int x = sprite.x + sprite.velocity.x
.

Il modo corretto per farlo sarebbe usare il tempo dall'ultimo rendering e aggiornare proporzionalmente. Il seguente codice presuppone 0,002 è il momento del tempo.

// FPS independent animation
int x = sprite.x + sprite.velocity.x * time_since_last_render/0.002
.

Su un dispositivo in cui il rendering richiede il doppio del tempo, il prossimo aggiornamento sposterà l'oggetto due volte più volte, quindi finisce nello stesso posto in quanto sarebbe su un dispositivo più veloce.

Un problema laterale, non dovresti sempre rendere il prossimo frame 0.002 secondi in futuro. Dovresti vedere per quanto tempo il telaio corrente ha preso per il rendering, sottrarre che da 0,002 e usarlo per pianificare il prossimo rendering. Naturalmente questo numero avrebbe un valore minimo di zero così sui dispositivi lenti non si avvia la programmazione nel passato. Ad esempio, se la funzione di rendering richiede esattamente 0,002 secondi per il rendering, questo ridurrà la frequenza fotogrammi della metà inutilmente.

Altri suggerimenti

Ci sono in realtà due tipi di frame rate:

    .
  • Frame frame: Vota a cui lo schermo è ridisegnato
  • Frequenza del fotogramma logico: Vota a cui è aggiornata la logica del gioco (Velocità di gioco)

Penso che tu stia cercando una frequenza fotogrammi logica costante che è disaccoppiata da una frequenza fotogrammi di visualizzazione che si adatta alla capacità dell'hardware del telefono.Confronta con il tuo ciclo di gioco che deve completare una cornice di visualizzazione per ogni cornice logica.

Dai un'occhiata alla "Velocità di gioco costante con algoritmo massimo di fps" descritto in Diewiter Game Loop La logica del gioco apparirà per funzionare alla stessa velocità su 3G e 2GS, ma la frequenza del fotogramma del display si adatta alla CPU di 2G più lente.Sebbene non sia coperto nell'articolo sopra, è anche possibile tappare la velocità del fotogramma del display per salvare la batteria.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top