Sleep time in un game loop

di il
2 risposte

Sleep time in un game loop

Salve a tutti,
in giro ci sono molte discussione riguardanti i game loop.

io uso questo tipo di game loop
public void run() {
    final int UPS=60; //UPS: update per second, in questo caso 60 update al secondo
    
    double delta=0d; //tiene il conto di quanto tempo (in secondi) manca per il prossimo update
    long previousTime=System.nanoTimer();

    running=true;
    while(running) {
        long now=System.nanoTime();
        delta+=(now-previousTime)/1000000000d; 
        //now-previousTime è il tempo in nanosecondi
        //trascorso dopo ogni iterazione;
        // dividiamo per 1000000000 per convertire in secondi
        previousTimer=now;

        while(delta>=1d/UPS) { //delta è almeno un 60-esimo di secondo
            update(delta) //update() si occupa di aggiornare la logica del gioco

            delta=-1d/UPS;
        }
        render() disegna gli elementi su schermo

        try {
            Thread.sleep(1); //QUI CERCO UNA SOLUZIONE !!!!!!!!!!
        }
        catch(InterruptedException e) {}
    }
}
Il tutto funziona bene.
Il problema sta nel Thread.sleep(1);
Se non lo metto l'uso della cpu aumenta in modo sconsiderato e questo vuol dire maggiore dissipazione di calore, maggior consumo di batteria (su notebook), ecc.

Se lo metto ho il dubbio che il thread rimanga in sleeping per più di un millisecondo (dipende dall'OS)
Inoltre su cpu più datate e meno performanti ho paura che si venga a determinare un calo di frame.

Mi servirebbe un modo per calcolare il tempo da inserire nello sleep, cosa mi consigliereste?

2 Risposte

  • Re: Sleep time in un game loop

    Generalmente non e' mai una gran soluzione utilizzare questo tipo di cicli.

    L'alternativa, comunque, e' abbastanza complicata: quello che si fa e' utilizzare un generatore di click che scandisce il tempo, e tutte le funzioni di aggiornamento partono allo scoccare del click e ragionano in base a quanto tempo e' passato dal precedente istante di tempo processato.

    In questo modo, se un'elaborazione richiede piu' click, il sistema comunque rimane in uno stato coerente e reattivo

    Praticamente come il clock del processore.

    Qui, l'eliminazione di Thread.sleep(1) introduce un ciclo molto stretto che impegna completamente un core (o l'intera CPU se in un sistema monocore).

    Per ridurre questo problema ci sono fondamentalmente due soluzioni:

    1) usare Thread.sleep(0)
    2) usare Thread.yield()

    entrambi forzano il context switch permettendo al computer di dedicare del tempo ad altri thread del sistema.
  • Re: Sleep time in un game loop

    A volte bisogna scendere a compromessi...
    Cioè il ciclo che io ho scritto rispetta i requisiti di 60 UPS se il tempo di completamento del metodo update più il tempo di completamento del metodo render si mantiene minore o uguale ad 1/60 secondi.

    Diciamo che non tutti i giochi sono giocabili su tutte le cpu, soprattutto le più datate.

    Comunque ora provo con Thread.sleep(0).

    EDIT:
    Ho provato ad inserire Thread.sleep(0) o Thread.yield() ma il risultato non era quello da me desiderato.
Devi accedere o registrarti per scrivere nel forum
2 risposte