2016-07-06 46 views
6

Domanda: La funzione update(currentTime:) in SKScene viene chiamata ogni frame con un argomento currentTime. Mi chiedo come ottenere il tempo dalla stessa fonte update(currentTime:) usi senza utilizzare la funzione update. Ho trovato solo CFAbsoluteTimeGetCurrent() che è diverso.Come ottenere lo stesso tempo utilizzato dalla funzione di aggiornamento (correnteTempo :)? (prima che venga chiamato)

Motivo: per calcolare timeSinceLastUpdate è necessaria una variabile di istanza denominata timeOfLastUpdate. Per implementare timeOfLastUpdate è necessario impostarlo su un valore arbitrario prima del primo aggiornamento che rende non corretto il primo calcolo di timeSinceLastUpdate. Si potrebbe avere una semplice istruzione if per rilevarlo o utilizzare optionals ma si tratta di un ramo non necessario che potrebbe essere evitato se si imposta timeOfLastUpdate in didMoveToView(view:). Ed è quello che sto cercando di fare.

+0

Ho notato che 'currentTime' restituisce il tempo in secondi in cui il dispositivo è stato in esecuzione, il che significa che viene ripristinato ogni volta che si riavvia. Ci sono modi per ottenere questo valore, ma per quello che stai facendo, la risposta di rickster è la strada da percorrere. – mogelbuster

risposta

4

Il primo timeSinceLastUpdate sarà sempre diverso dal resto. In genere si memorizza il tempo assoluto dalla precedente chiamata update e si sottrae dal tempo della chiamata corrente per ottenere un timeSinceLastUpdate. Se l'ora precedente non esiste perché sei al primo passaggio attraverso il ciclo di rendering - è impostato su zero o infinito o qualcosa di negativo o qualsiasi valore sentinella a cui hai inizializzato, basta impostare il tuo timeSinceLastUpdate su un valore nominale per iniziare . Qualcosa come il tuo intervallo di fotogrammi (16.67 ms se stai andando per 60 fps) avrebbe senso - non vuoi che il codice di gioco che dipende da quell'intervallo di tempo faccia qualcosa di selvaggio perché lo hai passato a zero o un enorme valore.

In realtà, non è una cattiva idea avere una logica per normalizzare il tuo timeSinceLastUpdate in qualcosa di sano nel caso in cui diventi troppo grande - ad esempio, perché l'utente ha fatto una pausa e ha ripreso il gioco. Se hai entità di gioco (come gli agenti GameplayKit) il cui movimento segue una sorta di modello position += velocity * timeSinceLastUpdate, vuoi che si spostino di un frame per un periodo di tempo quando riprendi da una pausa, non prendi una pausa di cinque minuti per velocity e salta a iperspazio.

Se si inizializza il tempo precedente a zero, sottrarre e normalizzare all'intervallo di fotogrammi previsto, verranno trattati sia i casi iniziali che quelli non validi con lo stesso codice.

+0

Mi chiedo come ottenere il tempo "precedente" dal metodo 'didMoveToView'. Poiché la soluzione corrente richiede la valutazione di un'espressione booleana ~ 60 volte al secondo, anche se è necessaria solo una volta al primo aggiornamento. – Mazen

+1

Come ho notato, il controllo booleano è utile/necessario per qualcosa di più del semplice aggiornamento. Ed è migliaia di volte più veloce di qualsiasi altra cosa tu stia facendo nel tuo metodo di aggiornamento: quello che sto ottenendo è che provare a inventare un tempo "precedente" fittizio solo per ottimizzare quel check-out è il pensare troppo. – rickster

2

Si può sempre usare COALESCE:

let deltaTime = currentTime - (previousTime ?? currentTime). 

Al primo ciclo, il vostro tempo delta è 0 (dovrebbe essere questo), dopo di che, è il cambiamento

Naturalmente previousTime deve essere un optional per questo lavoro