Pensare in comandi parte 1 di 2

Due volte al mese, rivisitiamo alcuni dei post preferiti dei nostri lettori da tutta la storia di Activetuts +. Questo tutorial è stato pubblicato per la prima volta nel marzo 2010 ed è la prima parte di una serie.

Il codice semplice e manutenibile è bello. Tuttavia, quando abbiamo una sequenza di azioni che devono attivarsi a vicenda, il nostro codice può diventare disordinato, rendendo impossibile cambiare in seguito. Il Modello di comando mantiene le cose pulite.

In questo tutorial, ti mostrerò come creare un framework di comandi AS3 minimalista, in grado di eseguire azioni in sequenza, in parallelo o con un ritardo. Ti sposterai su come utilizzare questo framework per creare un effetto complesso con un codice semplice e pulito.


Incapsulamento del comando

Incapsulare le istruzioni in "comandi" è un approccio di programmazione popolare per semplificare le cose: il modello di comando è in realtà uno degli schemi di progettazione più comunemente usati nella programmazione orientata agli oggetti. Fondamentalmente, il concetto di comando viene implementato creando classi di comando, ciascuna classe rappresenta un tipo di comando. Nel resto del tutorial, quando mi riferisco a "un comando", intendo "un oggetto comando".

Puoi pensare a un comando come un pulsante su un telecomando. Ogni pulsante fa qualcosa di diverso, ma sono tutti utilizzati allo stesso modo: lo premi, poi la magia accade. Accendendo la TV, cambiando i canali o regolando il volume, queste funzioni possono essere eseguite semplicemente premendo un pulsante.

Immagine per gentile concessione di freedigitalphotos.net

Il concetto di comandi è lo stesso. L'istruzione sottostante di un comando è proprio come la funzione di un pulsante di controllo remoto. È possibile incapsulare diverse istruzioni in comandi, ad esempio tracciare un messaggio semplice, spostare un oggetto da un luogo a un altro o attivare la visibilità di un oggetto di visualizzazione. Una volta eseguito l'incapsulamento, questi possono essere eseguiti semplicemente dicendo al programma di "premere i pulsanti del telecomando", o in altre parole, di "eseguire i comandi".

Se vuoi che il programma funzioni in modo diverso, puoi semplicemente cambiare il codice all'interno della classe Command: il programma esegue ancora gli stessi comandi che aveva precedentemente, ma il codice sottostante all'interno dei comandi è diverso. Il tuo elenco generale delle azioni che vuoi che il programma faccia è separato dal tuo elenco dettagliato di istruzioni su come ogni azione dovrebbe essere eseguita.


Perché preoccuparsi dei comandi?

"Un grosso problema", potresti dire, "Potrei farlo usando le funzioni. Perché preoccuparsi di usare i comandi?" Ok, diamo un'occhiata a due serie di codice che creano lo stesso effetto, una che usa le funzioni e l'altra che usa il framework dei comandi che creeremo in questo tutorial. Il vantaggio dei comandi diventerà chiaro.

Diciamo che vogliamo creare un cerchio, aggiungerlo al palco, interpolarlo da invisibile a visibile per mezzo secondo, attendere due secondi, tornare indietro invisibile per oltre mezzo secondo, e quindi rimuoverlo dallo stage. Per fare tutto questo useremo la classe TweenNano di Greensock.

Se stai usando solo le funzioni, il codice sarà simile a questo:

 var circle: Circle = new Circle (); addChild (cerchio); TweenNano.from (circle, 0.5, alpha: 0, onComplete: func1); function func1 (): void TweenNano.to (circle, 0.5, delay: 2, alpha: 0, onComplete: func2);  function func2 (): void removeChild (circle); 

Vedi come il nostro elenco di azioni è tutto aggrovigliato con le nostre istruzioni per eseguire ogni azione? Per capire cosa succederà, devi seguire tutto il onCompletes e vedi dove conducono.

Ecco lo stesso codice, utilizzando un framework di comando:

 var circle: Circle = new Circle (); comando var: Comando = new SerialCommand (0, new AddChild (this, circle), new TweenNanoFrom (circle, 0.5, alpha: 0), new TweenNanoTo (circle, 0.5, delay: 2, alpha: 0), nuovo RemoveChild (questo, cerchio)); command.start ();

Qui, AddChild (), TweenNanoFrom, TweenNanoTo, e RemoveChild sono tutte le classi di comando che definiamo altrove nel codice e SerialCommand è un'altra classe di comando che possiamo usare per creare sequenze di comandi al volo.

Risultato: non più funzione "salti". È chiaro cosa farà questa sequenza e in quale ordine. È anche facile cambiare l'ordine delle azioni o inserire una nuova azione tra quelle esistenti, senza dover cercare il codice per ogni azione e cambiarne il significato onComplete proprietà.

I comandi ci permettono anche di mettere in coda diverse azioni in modo che avvengano contemporaneamente, ma ci arriveremo più tardi!


La classe di comando

Un rapido esempio di lavoro vale più di mille parole, quindi diamo un'occhiata all'elemento essenziale del nostro framework di comando: la classe Command.

 comandi del pacchetto import flash.events.Event; import flash.events.EventDispatcher; import flash.events.TimerEvent; import flash.utils.Timer; Comando di classe pubblica estende EventDispatcher private var _timer: Timer; funzione pubblica Comando (delay: Number = 0) _timer = new Timer (int (1000 * delay), 1); _timer.addEventListener (TimerEvent.TIMER_COMPLETE, onTimerComplete);  funzione privata onTimerComplete (e: TimerEvent): void execute ();  / ** * Avvia il comando. * Attende il completamento del timer e chiama il metodo execute (). * Questo metodo può essere utilizzato direttamente come ascoltatore di eventi. * / public final function start (e: Event = null): void _timer.start ();  / ** * Il metodo astratto per te di sovrascrivere per creare il tuo comando. * / protected function execute (): void  / ** * Completa il comando. * Invia un evento completo. * Questo metodo può essere utilizzato direttamente come ascoltatore di eventi. * / protected final function complete (e: Event = null): void dispatchEvent (new Event (Event.COMPLETE)); 

Il metodo "più vuoto" è il metodo execute (); tuttavia, questo metodo è la parte più importante del comando. Per creare vari oggetti comando, devi estendere questa classe Command e sovrascrivere il metodo execute (), compilando le istruzioni che vuoi che il tuo programma esegua.

Per far funzionare un oggetto Command, si chiama il suo metodo start (); esegue il conto alla rovescia del tempo di ritardo utilizzando un oggetto Timer e chiama il metodo execute () quando il timer termina il conto alla rovescia. Un ritardo zero significa semplicemente che il metodo execute () dell'oggetto Command verrà chiamato subito dopo aver chiamato il suo metodo start ().

(Si noti che quando il comando è completo, si deve chiamare manualmente il metodo complete (), provocando l'invio di un evento COMPLETE. Lo scopo di questo metodo diventerebbe chiaro più avanti nel tutorial.)

A proposito, impostare il parametro dell'evento per i metodi start () e complete () con un valore predefinito nullo è solo la mia abitudine personale. In questo modo, i metodi possono essere chiamati come faresti con qualsiasi altro metodo a parametri zero, oppure possono essere usati direttamente come listener di eventi.


Esempio: traccia semplice

Ora che abbiamo la nostra classe Command, iniziamo a giocarci con alcune semplici traccie.


Passaggio 1: creare un documento Flash

Per prima cosa, dobbiamo aprire l'IDE Flash e creare un nuovo documento Flash. Chiamalo SimpleTracing.fla.


Passaggio 2: creare la classe del documento

Quindi, crea una classe di documento per questo documento Flash. Leggi questo suggerimento rapido per un'introduzione alle classi di documenti.

 pacchetto import flash.display.Sprite; public class SimpleTracing estende Sprite public function SimpleTracing () 

Salvalo come SimpleTracing.as.


Passaggio 3: creare la classe di comando di base

Crea un nuovo file AS e copia la classe Command (da sopra) in essa.

Crea una nuova cartella nel tuo classpath chiamata "comandi" e salva questo nuovo file AS come Command.as all'interno di quella cartella.


Passaggio 4: il comando traccia

Vorremmo iniziare incapsulando una funzione di traccia nei comandi, quindi estendiamo la classe Command per creare una classe TraceCommand per questo scopo. Questa classe conterrà una stringa di messaggi da tracciare quando viene chiamato il metodo execute (), e chiamerà il metodo complete () dopo la traccia.

 comandi del pacchetto public class TraceCommand estende Command private var _message: String; funzione pubblica TraceCommand (delay: Number, message: String) super (delay); _message = message;  override function protected execute (): void trace (_message); completare(); 

Salva questo come TraceCommand.as, anche nella cartella "comandi". Guarda come abbiamo scavalcato il eseguire() funzione per fare in modo che questo comando faccia effettivamente qualcosa?


Passaggio 5: traccia

Completa la classe del documento con oggetti TraceCommand. Aggiungi listener per l'evento COMPLETE di questi comandi.

 package import commands.Command; comandi di importazione. TraceCommand; import flash.display.Sprite; import flash.events.Event; public class SimpleTracing estende Sprite public function SimpleTracing () var command: Command; comando = new TraceCommand (0, "primo comando"); command.addEventListener (Event.COMPLETE, onCommandComplete); command.start (); command = new TraceCommand (1, "second command"); command.addEventListener (Event.COMPLETE, onCommandComplete); command.start (); comando = new TraceCommand (2, "terzo comando"); command.addEventListener (Event.COMPLETE, onCommandComplete); command.start ();  funzione privata onCommandComplete (e: Event): void trace ("un comando è completo"); 

Dire al programma di eseguire i comandi è semplice come chiamare i metodi start () degli oggetti Command. Prova il film e vedrai il seguente output, stampato riga per riga con un intervallo di tempo di un secondo. Inoltre, è possibile visualizzare i messaggi di interlacciamento stampati dal listener di eventi completo dei comandi. La stessa variabile è usata per contenere riferimenti a diversi oggetti Command, ma il programma fa la stessa cosa con la variabile: chiama il metodo start () e ascolta un evento COMPLETE.


Comandi compositi

Ci sono momenti in cui ti piacerebbe eseguire più comandi con tempi complessi. Qui introdurrò due tipi comuni di comandi che possono eseguire i tempi di comando avanzati: comandi paralleli e seriali. Entrambi sono comandi compositi, il che significa che contengono più sottocomandi. Controlliamoli uno per uno.


Comando parallelo

Un comando parallelo esegue tutti i suoi sottocomandi contemporaneamente o, in altre parole, in parallelo. Il comando è completo solo quando tutti i suoi sottocomandi sono completi. La seguente figura fornisce un concetto visivo di un comando parallelo. Le punte nere indicano il "flusso" dell'esecuzione del comando


La classe ParallelCommand

Ora è il momento di creare la nostra classe per i comandi paralleli.

Di seguito è riportato il codice completo per la classe ParallelCommand. Salvalo come ParallelCommand.as nella cartella "comandi".

I sottocomandi vengono passati al costruttore come? (resto) parametro. Questo ci permette di passare tutti i comandi che vogliamo al costruttore; saranno automaticamente messi in un array chiamato comandi. Vedremo la bellezza di questo particolare tipo di parametro molto presto.

 comandi del pacchetto import flash.events.Event; public class ParallelCommand estende Command private var _commands: Array; public function ParallelCommand (delay: Number ,? commands) //? comandi è il parametro "? (rest)" super (delay); _commands = comandi;  private var _completeCommandCount: int; sovrascrivi la funzione finale protetta execute (): void // imposta il conteggio completo dei comandi su zero _completeCommandCount = 0; per ogni comando (var: Command in _commands) // ascolta l'evento completo di un sottocomando? command.addEventListener (Event.COMPLETE, onSubcommandComplete); //? e avvia il sottocomando command.start ();  funzione privata onSubcommandComplete (e: Event): void // interrompe l'ascolto per l'evento completo Command (e.target) .removeEventListener (Event.COMPLETE, onSubcommandComplete); // incrementa il conteggio dei comandi completo _completeCommandCount ++; // se tutti i comandi sono completi? if (_completeCommandCount == _commands.length) //? allora questo comando parallelo è completo completo (); 

Questa classe sovrascrive il metodo execute (); il nuovo metodo execute () ora chiama il metodo start () di tutti i sottocomandi e ascolta i loro eventi COMPLETE. Il listener di eventi COMPLETE per i sottocomandi conta quanti sottocomandi sono stati completati; una volta che tutti i sottocomandi sono stati eseguiti, viene chiamato il metodo complete () di ParallelCommand e invia un evento COMPLETO proprio.


Esempio: traccia parallela

Proviamo la classe ParallelCommand. Crea un nuovo documento Flash, copia la cartella "commands" nel suo classpath e scrivi una nuova classe di documento come di seguito:

 package import commands.Command; import commands.ParallelCommand; comandi di importazione. TraceCommand; import flash.display.Sprite; import flash.events.Event; public class ParallelTracing estende Sprite public function ParallelTracing () var parallelCommand: Command = new ParallelCommand (0, new TraceCommand (0, "1st of 3"), new TraceCommand (0, "2nd of 3"), new TraceCommand (0 , "3 ° di 3"),); parallelCommand.addEventListener (Event.COMPLETE, onCommandComplete); parallelCommand.start ();  funzione privata onCommandComplete (e: Event): void trace ("tutti i comandi sono completi"); 

Il vantaggio dell'utilizzo del parametro "? (Rest)" per il parametro del costruttore ora diventa evidente. È possibile formattare i sottocomandi con il rientro del codice corretto per scrivere codici visivamente auto-esplicativi.

Prova il film e vedrai i tre messaggi tracciati allo stesso tempo, quindi un messaggio finale che indica il completamento del comando parallelo:

  • 1 ° di 3
  • 2 di 3
  • 3 di 3
  • tutti i comandi sono completi

Per quanto riguarda la configurazione dei ritardi all'interno di un comando parallelo? Semplice. Cambia la funzione di costruzione della classe del documento in questo modo:

 public function ParallelTracing () var parallelCommand: Command = new ParallelCommand (0, new TraceCommand (0, "first wave, 1st of 2"), new TraceCommand (0, "first wave, 2nd of 2"), new TraceCommand (1 , "seconda ondata, 1 ° di 3"), nuovo TraceCommand (1, "seconda ondata, 2 ° di 3"), nuovo TraceCommand (1, "seconda ondata, 3 ° di 3"), nuovo TraceCommand (2, "ultima onda, 1st of 2 "), new TraceCommand (2," last wave, 2nd of 2 ")); parallelCommand.addEventListener (Event.COMPLETE, onCommandComplete); parallelCommand.start (); 

Prova il film e vedrai le seguenti tre ondate di messaggi stampati, con un intervallo di tempo di un secondo tra ogni onda:

  • prima ondata, 1 ° di 2
  • prima ondata, 2 ° di 2


  • seconda ondata, 1 ° di 3
  • seconda ondata, 2 ° di 3
  • seconda ondata, 3 ° di 3


  • ultima ondata, 1 ° di 2
  • ultima ondata, 2 di 2

Per avere una migliore idea di cosa sta succedendo, guarda questa illustrazione:


Comando seriale

Il secondo tipo di comando composito è il comando seriale. Un comando seriale esegue i sottocomandi uno dopo l'altro o, in altre parole, in serie. Ad esempio, il secondo comando viene eseguito dopo il completamento del primo e il terzo viene eseguito dopo il completamento del secondo. La seguente figura fornisce un concetto visivo di un comando seriale:


La classe SerialCommand

Ecco il codice sorgente per la classe SerialCommand. Il metodo execute () sottoposto a override chiama il metodo start () del primo sottocomando e ascolta il suo evento COMPLETE. Quindi, il listener di eventi avvia il sottocomando successivo e ascolta il suo evento COMPLETE e così via, fino a quando non vengono completati tutti i sottocomandi. A quel punto viene inviato l'evento COMPLETE per l'intero SerialCommand.

 comandi del pacchetto import flash.events.Event; public class SerialCommand estende Command private var _commands: Array; funzione pubblica SerialCommand (delay: Number ,? commands) super (delay); _commands = comandi;  private var _completeCommandCount: int; sovrascrivi la funzione finale protetta execute (): void // imposta il conteggio completo dei comandi su zero _completeCommandCount = 0; // ascolta l'evento completo del primo sottocomando? _commands [0] .addEventListener (Event.COMPLETE, onSubcommandComplete); //? e avvia il sottocomando _commands [0] .start ();  funzione privata onSubcommandComplete (e: Event): void // interrompe l'ascolto per l'evento completo Command (e.target) .removeEventListener (Event.COMPLETE, onSubcommandComplete); // incrementa il conteggio dei comandi completo _completeCommandCount ++; // se tutti i comandi sono completi? if (_completeCommandCount == _commands.length) //? allora questo comando seriale è completo ();  altro  //? altrimenti ascolta l'evento completo del sottocomando successivo? _commands [_completeCommandCount] .addEventListener (Event.COMPLETE, onSubcommandComplete); //? e avvia il sottocomando _commands [_completeCommandCount] .start (); 

Esempio: traccia seriale

Usiamo la classe SerialCommand per fare qualche traccia seriale. Come prima, crea un nuovo documento Flash, copia la cartella "comandi" e scrivi una nuova classe di documento:

 package import commands.Command; import commands.SerialCommand; comandi di importazione. TraceCommand; import flash.display.Sprite; import flash.events.Event; public class SerialTracing estende Sprite public function SerialTracing () var serialCommand: Command = new SerialCommand (0, new TraceCommand (0, "first command"), new TraceCommand (1, "second command"), new TraceCommand (1, " terzo comando ")); serialCommand.addEventListener (Event.COMPLETE, onCommandComplete); serialCommand.start ();  funzione privata onCommandComplete (e: Event): void trace ("tutti i comandi sono completi"); 

Prova il film e i seguenti messaggi vengono tracciati uno ad uno, con un intervallo di tempo di un secondo, seguito da "tutti i comandi sono completi".

  • primo comando


  • secondo comando


  • terzo comando

Ecco una figura concettuale di questo esempio che ti aiuta a capire meglio cosa sta succedendo.


Comandi compositi nidificati

Finora, abbiamo solo esplorato l'uso più basilare dei comandi paralleli e seriali, e non sembra esserci alcun motivo per usarli al posto di comandi separati. Tuttavia, in alcuni casi sono necessarie esecuzioni di comandi molto più complesse e si possono combinare più comandi compositi per creare comandi nidificati in base alle proprie esigenze. Il prossimo esempio mostra come utilizzare la classe ParallelCommand e la classe SerialCommand per creare comandi nidificati di questo tipo.


Esempio: comandi nidificati

Come prima, crea un nuovo documento Flash, copia la cartella "comandi" e scrivi una nuova classe di documento:

 package import commands.Command; import commands.ParallelCommand; import commands.SerialCommand; comandi di importazione. TraceCommand; import flash.display.Sprite; import flash.events.Event; public class NestedCommands estende Sprite public function NestedCommands () var nestedCommands: Command = new SerialCommand (0, new ParallelCommand (0, new TraceCommand (0, "parallel command # 1, part 1 of 2"), new TraceCommand (0, "comando parallelo # 1, parte 2 di 2"), nuovo TraceCommand (0, "------------------------------- - ")), nuovo ParallelCommand (1, nuovo TraceCommand (0," comando parallelo # 2, parte 1 di 3 "), nuovo TraceCommand (0," comando parallelo # 2, parte 2 di 3 "), nuovo TraceCommand (0 , "comando parallelo # 2, parte 3 di 3"), nuovo TraceCommand (0, "------------------------------ - ")), nuovo ParallelCommand (1, nuovo TraceCommand (0," ultimo comando "), nuovo TraceCommand (0," ---------------------- ---------- "))); nestedCommands.addEventListener (Event.COMPLETE, onCommandComplete); nestedCommands.start ();  funzione privata onCommandComplete (e: Event): void trace ("tutti i comandi sono completi"); 

Prova il film e il programma stamperà il seguente messaggio blocchi uno alla volta, con un intervallo di tempo di un secondo. Come negli esempi precedenti, verrà stampato un messaggio finale completo quando tutti i sottocomandi saranno completi.

  • comando parallelo n. 1, parte 1 di 2
  • comando parallelo n. 1, parte 2 di 2
  • --------------------------------


  • comando parallelo n. 2, parte 1 di 3
  • comando parallelo n. 2, parte 2 di 3
  • comando parallelo n. 2, parte 3 di 3
  • --------------------------------


  • ultimo comando
  • --------------------------------

Ecco la figura concettuale di questo esempio.


Esempio: circuito di luce

Infine, diamo un'occhiata ad un esempio più pratico. Utilizzeremo il quadro dei comandi che abbiamo creato per creare una demo del circuito di luce, con tempi avanzati. Prima di iniziare, (hai indovinato) crea un nuovo documento Flash, copia la cartella "comandi" e crea una nuova classe di documento.


Step 1: Il simbolo della luce

Crea un simbolo di clip filmato, con un'animazione della linea temporale in cui un cerchio cambia colore da grigio a giallo.

Nella timeline, all'ultimo keyframe, aggiungi il seguente codice. Ciò impedisce al filmato di animare e inviare un evento COMPLETO:

 Stop(); dispatchEvent (new Event (Event.COMPLETE));

Se vuoi evitare di scrivere codice sulla timeline, puoi creare una classe per il tuo clip filmato leggero, con una funzione:

 funzione pubblica ha raggiuntoEndOfAnimation (): void stop (); dispatchEvent (new Event (Event.COMPLETE)); 

? e quindi nel costruttore per quella classe, scrivi quanto segue:

 addFrameScript (4, reachedEndOfAnimation) // dove 4 è uno in meno del numero di frame

Passaggio 2: il circuito

Disporre istanze di luce sul palco e nominarle come mostrato nella seguente figura:


Passaggio 3: interazione

Trascina un componente Button dal pannello Componenti sullo stage e chiamalo "start_btn". Vogliamo eseguire i nostri comandi quando viene premuto questo pulsante.


Passaggio 4: indicatore di completamento

Crea un campo di testo sullo stage e digita il messaggio di completamento. Successivamente, convertirlo in un simbolo di clip filmato e denominare l'istanza "completeMessage_mc".


Passaggio 5: la classe del documento

Ora è il momento di modificare la classe del documento. Dichiarare una variabile privata "circuitCommand", che verrà utilizzata per contenere un riferimento a un oggetto Command:

 private var circuitCommand: Command;

All'inizio del programma, tutte le luci devono essere spente, cioè si fermano al primo fotogramma e il messaggio di completamento deve essere nascosto. Quindi chiamiamo il metodo reset () nel costruttore.

 reset();

Quindi, crea i nostri comandi nidificati che riproducono le animazioni dei clip di luce, illuminandole con il giusto tempismo. Qui usiamo una classe PlayCommand, che chiama semplicemente il metodo play () di un clip filmato. Scriveremo la lezione più tardi.

 circuitCommand = new SerialCommand (0.5, nuovo PlayCommand (0, light_1), nuovo ParallelCommand (0.5, nuovo PlayCommand (0, light_2_1), nuovo PlayCommand (0, light_2_2)), nuovo PlayCommand (0.5, light_3), nuovo ParallelCommand (0.5, nuovo PlayCommand (0, light_4_1), nuovo PlayCommand (0, light_4_2)), nuovo PlayCommand (0.5, light_5));

Quindi, ascolta l'evento COMPLETE del comando e l'evento CLICK del pulsante di avvio:

 circuitCommand.addEventListener (Event.COMPLETE, onCommandComplete); start_btn.addEventListener (MouseEvent.CLICK, startCircuit);

Passaggio 6: aggiungere gestori di eventi

Mostra il messaggio di completamento quando il comando è completato:

 funzione privata onCommandComplete (e: Event): void completeMessage_mc.visible = true; 

Resetta il circuito e avvia il comando quando si fa clic sul pulsante di avvio.

 funzione privata startCircuit (e: MouseEvent): void reset (); circuitCommand.start (); 

Passaggio 7: il metodo di ripristino

L'ultima parte per la classe del documento è il metodo reset (). Niente a che vedere con i comandi qui.

 funzione privata reset (): void completeMessage_mc.visible = false; light_1.gotoAndStop (1); light_2_1.gotoAndStop (1); light_2_2.gotoAndStop (1); light_3.gotoAndStop (1); light_4_1.gotoAndStop (1); light_4_2.gotoAndStop (1); light_5.gotoAndStop (1); 

Passaggio 8: la classe PlayCommand

L'ultima parte di questo esempio è la classe PlayCommand. Come accennato in precedenza, ciò che fa è semplice come chiamare il metodo play () di un clip filmato. Non appena viene chiamato il metodo play () nel metodo execute () sovrascritto del comando, viene chiamato anche il metodo complete ().

 comandi del pacchetto import flash.display.MovieClip; import flash.events.Event; la classe pubblica PlayCommand estende Command private var _movieClip: MovieClip; funzione pubblica PlayCommand (delay: Number, movieClip: MovieClip) super (delay); _movieClip = movieClip;  override function protected execute (): void _movieClip.addEventListener (Event.COMPLETE, complete); _movieClip.play (); 

Salva questo come PlayCommand.as nella cartella "comandi".


Passaggio 9: test del film

Va bene, abbiamo finito! Ora prova il film e vedrai le luci accese da sinistra a destra dopo aver fatto clic sul pulsante di avvio. Il messaggio di completamento viene visualizzato quando tutte le luci sono accese.

Ecco la rappresentazione visiva di ciò che sta accadendo in questo esempio:

Confrontalo con il codice reale e vedi come è facile capire:

 nuovo SerialCommand (0.5, nuovo PlayCommand (0, light_1), nuovo ParallelCommand (0.5, nuovo PlayCommand (0, light_2_1), nuovo PlayCommand (0, light_2_2)), nuovo PlayCommand (0.5, light_3), nuovo ParallelCommand (0.5, nuovo PlayCommand (0, light_4_1), nuovo PlayCommand (0, light_4_2)), nuovo PlayCommand (0.5, light_5));

Ancora una volta, con il corretto indentazione del codice, un comando nidificato complesso può essere espresso come codice semplice e pulito.


Sommario

In questo tutorial hai imparato il concetto di comandi. Le istruzioni possono essere incapsulate in comandi che hanno interfacce identiche, proprio come ogni pulsante su un telecomando ha un'azione diversa, ma il metodo per invocare ogni azione è lo stesso: premere il pulsante.

Inoltre, questo tutorial ha introdotto due tipi di comandi compositi: parallelo e seriale. Questi possono essere utilizzati per creare comandi nidificati che consentono una sincronizzazione avanzata dei comandi mantenendo il codice pulito.


Conclusione

Il concetto di comandi è molto conveniente e potente. L'incapsulamento di codice è l'approccio principale per semplificare le cose durante la programmazione, e uno dei metodi più comunemente usati è l'uso di oggetti di comando. Spero che questo tutorial ti aiuti a capire meglio come usare i comandi nelle applicazioni pratiche.

Nella prossima parte di questo tutorial, ti mostrerò come integrare TweenLite con il framework dei comandi che abbiamo creato in questo tutorial, quindi gestire le transizioni di scena con codice semplice e pulito. Grazie mille per la lettura.