CAPITOLO 6.3

Tempo e Timer

Intermedio
~12 min
55 min

La classe Time

La classe Time ci permette di accedere alle proprietà legate all'orologio interno della scena. Quando viene creata un'istanza di Phaser.Game, il timer interno viene automaticamente inizializzato e avviato.

this.time.now

La proprietà now restituisce il tempo trascorso in millisecondi dall'inizializzazione del gioco:

update() {
  console.log(this.time.now); // es: 3542.5
}

È utile per calcolare delta temporali e sincronizzare eventi al tempo di gioco.

TimerEvent

this.time.addEvent() permette di eseguire del codice dopo un certo ritardo, o ripetutamente a intervalli regolari. Funziona come un setTimeout / setInterval, ma è sincronizzato con il ciclo di gioco di Phaser e si ferma automaticamente con la scena.

Esecuzione singola

create() {
  this.time.addEvent({
    delay: 1000,
    callback: () => { console.log('eseguito dopo 1 secondo'); },
    callbackScope: this,
  });
}

Esecuzione ripetuta

create() {
  this.time.addEvent({
    delay: 1000,
    callback: () => { this.myFunction(); },
    callbackScope: this,
    repeat: 2,   // oppure: loop: true per infinito
  });
}

myFunction() {
  console.log('eseguito ogni secondo');
}

Non usare repeat e loop: true contemporaneamente. Usa repeat per un numero definito di ripetizioni, o loop: true per una ripetizione infinita.

Parametri del TimerEvent

ProprietàTipoDescrizione
delaynumberTempo in ms prima dell'esecuzione
callbackFunctionFunzione da eseguire
callbackScopeobjectContesto this della callback (di solito this)
repeatnumberNumero di ripetizioni aggiuntive dopo la prima
loopbooleanSe true, si ripete indefinitamente
startAtnumberFa partire il timer come se startAt ms fossero già trascorsi
argsany[]Array di argomenti passati alla callback

Passare argomenti alla callback

private _myTimer: Phaser.Time.TimerEvent;

create() {
  this._myTimer = this.time.addEvent({
    delay: 1000,
    callback: (param1: number, param2: string) => {
      this.myFunction(param1, param2);
    },
    args: [42, 'ciao'],
    callbackScope: this,
  });
}

myFunction(param1: number, param2: string) {
  console.log(param1, param2); // 42 "ciao"
}

L'attributo args accetta un array di parametri che vengono passati alla callback nell'ordine indicato.

Distruggere il timer

Quando il timer non è più necessario, è buona pratica distruggerlo per liberare risorse:

if (this._myTimer != null) {
  this._myTimer.destroy();
}

Consulta la documentazione ufficiale: Namespace Time

Sequenziare più eventi nel tempo

Phaser 3.9 non dispone ancora della Timeline (introdotta molte versioni dopo). Per sequenziare più azioni in momenti diversi del futuro — utile per cutscene e tutorial — si combinano più TimerEvent con delay progressivi:

create() {
  // dopo 1 secondo: fa apparire un nemico
  this.time.addEvent({
    delay: 1000,
    callback: () => { this.spawnEnemy(); },
    callbackScope: this,
  });

  // dopo 2 secondi: avvia un'animazione
  this.time.addEvent({
    delay: 2000,
    callback: () => { this._helloWorld.play('intro-animation'); },
    callbackScope: this,
  });

  // dopo 3 secondi: mostra un testo
  this.time.addEvent({
    delay: 3000,
    callback: () => { this._helloWorld.setText('Via!'); },
    callbackScope: this,
  });
}
Phaser Labs
Phaser LabsLIVE
Prova tutto dal vivo — centinaia di esempi interattivi
Phaser Labs raccoglie esempi funzionanti per ogni argomento del corso. Copia, modifica, sperimenta — direttamente nel browser.
Apri gli esempi della classe TIME

Timeline

A differenza di una Timeline unica, ogni TimerEvent va gestito (e distrutto) separatamente. Per sequenze semplici di 2-3 passaggi va benissimo; per cutscene molto complesse, valuta di incapsulare la logica in un piccolo metodo dedicato come playIntroSequence().

Phaser Labs
Phaser LabsLIVE
Prova tutto dal vivo — centinaia di esempi interattivi
Phaser Labs raccoglie esempi funzionanti per ogni argomento del corso. Copia, modifica, sperimenta — direttamente nel browser.
Apri gli esempi della classe TIMELINE
Sh4rk0

Regola numero uno: mai usare setTimeout in Phaser. So che la tentazione c'è — lo usi da sempre, lo conosci, funziona. Ma setTimeout non sa che il gioco esiste: continua a girare anche quando la scena è in pausa, quando la finestra è in background, quando il tab è inattivo.

this.time.addEvent() si sincronizza con il game loop. Si ferma quando la scena si ferma, si distrugge quando la scena si distrugge. È quello che vuoi sempre.

Concatenare più TimerEvent con delay progressivi è il modo più semplice per raccontare qualcosa nel tempo: "dopo 1 secondo appare il nemico, dopo 2 secondi parte l'animazione, dopo 3 secondi arriva il testo". Non è elegante come una Timeline dedicata, ma fa il suo lavoro egregiamente. ⏱️