Denken in commando's deel 1 van 2

Twee keer per maand bekijken we enkele van onze favoriete lezers uit de geschiedenis van Activetuts +. Deze tutorial werd voor het eerst gepubliceerd in maart 2010 en is het eerste deel van een serie.

Eenvoudige, onderhoudbare code is prachtig. Als we echter een reeks acties hebben die elkaar moeten activeren, kan onze code rommelig worden, waardoor het onmogelijk is om later te veranderen. De Commandopatroon houdt dingen schoon.

In deze zelfstudie laat ik u zien hoe u een minimalistisch AS3-opdrachtraamwerk kunt maken dat in staat is om opeenvolgend, parallel of met vertraging acties uit te voeren. U leert hoe u dit framework kunt gebruiken om een ​​complex effect te creëren met eenvoudige en schone code.


Command Encapsulation

Het encapsuleren van instructies in "commando's" is een populaire programmeermethode om dingen te vereenvoudigen - het opdrachtpatroon is eigenlijk een van de meest gebruikte ontwerppatronen in objectgeoriënteerd programmeren. In principe wordt het opdrachtconcept geïmplementeerd door opdrachtklassen te maken, waarbij elke klasse één type opdracht vertegenwoordigt. In de rest van de tutorial, wanneer ik verwijs naar "een commando", bedoel ik "een commando-object".

Je kunt een opdracht zien als een knop op een afstandsbediening. Elke knop doet iets anders, maar ze worden allemaal op dezelfde manier gebruikt: je drukt erop en de magie gebeurt. Of het nu gaat om het inschakelen van de tv, het wijzigen van de kanalen of het aanpassen van het volume, deze functies kunnen allemaal worden gedaan door eenvoudig op een knop te drukken.

Afbeelding met dank aan freedigitalphotos.net

Het concept van commando's is hetzelfde. De onderliggende instructie van een commando is net als de functie van een afstandsbedieningsknop. U kunt verschillende instructies inkapselen in opdrachten, zoals het traceren van een eenvoudig bericht, het verplaatsen van het ene object van de ene naar de andere locatie of het omschakelen van de zichtbaarheid van een weergaveobject. Zodra de inkapseling is voltooid, kunnen deze eenvoudig worden uitgevoerd door het programma te vertellen "op de knoppen van de afstandsbediening te drukken" of met andere woorden om "de opdrachten uit te voeren".

Als je wilt dat het programma anders werkt, kun je gewoon de code binnen de Command-klasse veranderen: het programma voert nog steeds dezelfde commando's uit die het eerder deed, maar de onderliggende code binnen de commando's is anders. Uw algemene lijst met acties die u met het programma wilt uitvoeren, is gescheiden van uw gedetailleerde lijst met instructies voor hoe elke actie moet worden uitgevoerd.


Waarom last van commando's??

"Dikke deal," zou je kunnen zeggen, "Ik zou dat kunnen doen met behulp van functies.Waarom last van het gebruik van opdrachten?" Oké, laten we kijken naar twee sets code die hetzelfde effect creëren, een met behulp van functies en de andere met behulp van het opdrachtraamwerk dat we in deze zelfstudie maken. Het voordeel van commando's zal duidelijk worden.

Laten we zeggen dat we een cirkel willen maken, deze aan het podium willen toevoegen, tween van onzichtbaar tot zichtbaar in meer dan een halve seconde, twee seconden wachten, tussen weer terug onzichtbaar zijn gedurende nog een halve seconde en het dan van het podium verwijderen. Om dit allemaal te doen, zullen we de TweenNano-klasse van Greensock gebruiken.

Als u alleen functies gebruikt, ziet de code er als volgt uit:

 var circle: Circle = new Circle (); addChild (cirkel); TweenNano.from (cirkel, 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); 

Zie je hoe onze lijst met acties verweven is met onze instructies voor het uitvoeren van elke actie? Om erachter te komen wat er gaat gebeuren, moet je alle onCompleteen zie waar ze naartoe leiden.

Hier is dezelfde code, met behulp van een command framework:

 var circle: Circle = new Circle (); var command: Command = new Serial Commando (0, nieuw AddChild (this, circle), new TweenNanoFrom (circle, 0.5, alpha: 0), new TweenNanoTo (circle, 0.5, delay: 2, alpha: 0), nieuw RemoveChild (dit, cirkel)); command.start ();

Hier, AddChild (), TweenNanoFrom, TweenNanoTo, en removeChild zijn alle opdrachtklassen die we elders in de code definiëren, en SerialCommand is een andere Command-klasse die we kunnen gebruiken om reeksen commando's te creëren tijdens de vlucht.

Resultaat: niet meer functie "springt". Het is duidelijk wat deze volgorde gaat doen en in welke volgorde. Het is ook eenvoudig om de volgorde van de acties te wijzigen of een nieuwe actie tussen bestaande acties in te voegen, zonder dat u rond de code hoeft te jagen voor elke actie en zijn onComplete eigendom.

Commando's laten ons ook verschillende acties in de wachtrij plaatsen zodat ze tegelijkertijd gebeuren - maar daar komen we later op terug!


De commandoklasse

Een snel werkend voorbeeld is meer waard dan duizend woorden, dus laten we eens kijken naar het essentiële element van ons command framework: de klasse Command.

 pakketopdrachten import flash.events.Event; import flash.events.EventDispatcher; import flash.events.TimerEvent; import flash.utils.Timer; public class Command breidt EventDispatcher uit private var _timer: Timer; public function Command (delay: Number = 0) _timer = new Timer (int (1000 * delay), 1); _timer.addEventListener (TimerEvent.TIMER_COMPLETE, onTimerComplete);  private function onTimerComplete (e: TimerEvent): void execute ();  / ** * Start het commando. * Wacht tot de timer is voltooid en roept de methode execute () aan. * Deze methode kan direct als een gebeurtenislistener worden gebruikt. * / public final function start (e: Event = null): void _timer.start ();  / ** * De abstracte methode die u wilt overschrijven om uw eigen opdracht te maken. * / beschermde functie execute (): void  / ** * voltooit de opdracht. * Verzendt een compleet evenement. * Deze methode kan direct als een gebeurtenislistener worden gebruikt. * / beschermde laatste functie voltooid (e: Event = null): void dispatchEvent (new Event (Event.COMPLETE)); 

De "meest lege" methode is de methode execute (); deze methode is echter het belangrijkste onderdeel van het commando. Om verschillende opdrachtobjecten te maken, moet u deze opdrachtklasse uitbreiden en de methode execute () overschrijven, waarbij u de instructies opgeeft die u wilt dat uw programma uitvoert.

Om een ​​Command-object te laten werken, roept u de methode start () aan; het telt de vertragingstijd af met behulp van een Timer-object en roept de methode execute () aan wanneer de timer het aftellen voltooit. Een nulvertragingstijd betekent gewoon dat de methode execute () van het Command-object wordt aangeroepen direct nadat u de methode start () aanroept.

(Merk op dat wanneer uw opdracht is voltooid, u de methode complete () handmatig moet aanroepen, waardoor deze een COMPLETE-gebeurtenis verzendt. Het doel van deze methode wordt later in de zelfstudie duidelijker.)

Trouwens, het instellen van de parameter event voor de methoden start () en complet () met een nulwaarde is gewoon mijn persoonlijke gewoonte. Op deze manier kunnen de methoden worden opgeroepen zoals u met andere zero-parametermethoden zou doen, of ze kunnen direct worden gebruikt als gebeurtenislisteners.


Voorbeeld: Simple Tracing

Nu we onze Command-klasse hebben, laten we ermee beginnen spelen met enkele eenvoudige tracering.


Stap 1: Maak een Flash-document

Allereerst moeten we de Flash-IDE openen en een nieuw Flash-document maken. Noem het SimpleTracing.fla.


Stap 2: Maak de documentklasse

Maak vervolgens een documentklasse voor dit Flash-document. Lees deze snelle tip voor een introductie tot documentklassen.

 pakket import flash.display.Sprite; openbare klasse SimpleTracing breidt uit openbare functie SimpleTracing () 

Sla het op als SimpleTracing.as.


Stap 3: Maak de Base Command Class

Maak een nieuw AS-bestand en kopieer de Command-klasse (van boven) erin.

Maak een nieuwe map in uw klassenpad met de naam "commands" en sla dit nieuwe AS-bestand op als Command.as in die map.


Stap 4: Het traceercommando

We willen beginnen met het inkapselen van een traceerfunctie in opdrachten, dus laten we de klasse Command uitbreiden om hiervoor een TraceCommand-klasse te maken. Deze klasse bevat een berichtreeks die kan worden getraceerd wanneer de methode execute () wordt aangeroepen en de methode complete () na de tracering wordt aangeroepen.

 pakketopdrachten public class TraceCommand breidt opdracht uit private var _message: String; public function TraceCommand (delay: Number, message: String) super (delay); _message = bericht;  override protected function execute (): void trace (_message); compleet(); 

Sla deze op als TraceCommand.as, ook in de map "commands". Zie hoe we het hebben onderdrukt execute () functie om deze opdracht daadwerkelijk iets te laten doen?


Stap 5: Traceren

Voltooi de documentklasse met TraceCommand-objecten. Voeg luisteraars toe voor de COMPLETE gebeurtenis van deze opdrachten.

 pakket import commands.Command; importeer commando's. TikCommand; import flash.display.Sprite; import flash.events.Event; openbare klasse SimpleTracing breidt uit openbare functie SimpleTracing () var command: Command; command = new TraceCommand (0, "first command"); command.addEventListener (Event.COMPLETE, onCommandComplete); command.start (); command = new TraceCommand (1, "second command"); command.addEventListener (Event.COMPLETE, onCommandComplete); command.start (); command = new TraceCommand (2, "third command"); command.addEventListener (Event.COMPLETE, onCommandComplete); command.start ();  private function onCommandComplete (e: Event): void trace ("een opdracht is voltooid"); 

Het programma vertellen om de opdrachten uit te voeren, is net zo eenvoudig als het aanroepen van de start () -methoden van de opdrachtobjecten. Test de film en u ziet de volgende uitvoer, regel voor regel afgedrukt met een tijdsverschil van één seconde. U kunt ook de interliniëringsberichten zien afgedrukt door de complete gebeurtenislistener van de opdrachten. Dezelfde variabele wordt gebruikt om verwijzingen naar verschillende opdrachtobjecten te houden, maar het programma doet hetzelfde met de variabele: bel de start () -methode en luister naar een COMPLETE-gebeurtenis.


Samengestelde opdrachten

Er zijn tijden dat u meerdere opdrachten met complexe timing wilt uitvoeren. Hier zal ik twee veel voorkomende soorten commando's introduceren die een geavanceerde commandotiming kunnen uitvoeren: parallelle en seriële commando's. Beide zijn samengestelde opdrachten, wat betekent dat ze meerdere subopdrachten bevatten. Laten we ze een voor een bekijken.


Parallel Command

Een parallelle opdracht voert alle subopdrachten tegelijk uit - of, met andere woorden, parallel. De opdracht is alleen voltooid als alle subopdrachten compleet zijn. De volgende afbeelding geeft een visueel concept van een parallelle opdracht. De zwarte pijlpunten geven de "stroom" van de uitvoering van de opdracht aan


De ParallelCommand-klasse

Nu is het tijd om onze klasse te maken voor parallelle commando's.

Hieronder ziet u de volledige code voor de klasse ParallelCommand. Sla het op als ParallelCommand.as in de map "commands".

De subopdrachten worden doorgegeven aan de constructor als de? (rust) parameter. Dit laat ons zoveel opdrachten doorgeven als we willen aan de constructeur; ze worden automatisch in een array geplaatst die wordt genoemd commando's. We zullen de schoonheid van dit speciale type parameter zeer binnenkort zien.

 pakketopdrachten import flash.events.Event; public class ParallelCommand breidt Command uit private var _commands: Array; openbare functie ParallelCommand (delay: Number ,? commands) //? commando's is de "? (rest)" parameter super (delay); _commands = opdrachten;  private var _completeCommandCount: int; override final protected function execute (): void // stel het volledige aantal opdrachten in op nul _completeCommandCount = 0; voor elk (var-commando: Commando in _commands) // luister naar de complete gebeurtenis van een subopdracht? command.addEventListener (Event.COMPLETE, onSubcommandComplete); //? en start de opdracht subcommand.start ();  persoonlijke functie onSubcommandComplete (e: Event): void // stop listening for the complete event Command (e.target) .removeEventListener (Event.COMPLETE, onSubcommandComplete); // verhoog het volledige aantal opdrachten _completeCommandCount ++; // als alle opdrachten voltooid zijn? if (_completeCommandCount == _commands.length) //? dan is deze parallelle opdracht compleet voltooid (); 

Deze klasse overschrijft de methode execute (); de nieuwe methode execute () roept nu de methode start () van alle subopdrachten aan en luistert naar hun COMPLETE-gebeurtenissen. De COMPLETE-gebeurtenislistener voor de subopdrachten telt hoeveel subopdrachten zijn voltooid; Zodra alle subopdrachten zijn voltooid, wordt de methode complete () van de ParallelCommand aangeroepen en wordt een COMPLETE-gebeurtenis verzonden.


Voorbeeld: parallelle tracering

Laten we de ParallelCommand-klasse uitproberen. Maak een nieuw Flash-document, kopieer de map "commands" naar het classpath en schrijf een nieuwe documentklasse, zoals hieronder:

 pakket import commands.Command; importeer commando's. ParallelCommand; importeer commando's. TikCommand; import flash.display.Sprite; import flash.events.Event; public class ParallelTracing breidt Sprite uit openbare functie ParallelTracing () var parallelCommand: Command = new ParallelCommand (0, nieuwe TraceCommand (0, "1st of 3"), nieuwe TraceCommand (0, "2nd of 3"), nieuwe TraceCommand (0 , "3e van 3"),); parallelCommand.addEventListener (Event.COMPLETE, onCommandComplete); parallelCommand.start ();  private function onCommandComplete (e: Event): void trace ("alle opdrachten zijn voltooid"); 

Het voordeel van het gebruik van de parameter "? (Rest)" voor de constructorfactor wordt nu duidelijk. U kunt de subopdrachten opmaken met de juiste code-inspringing om visueel zelfverklarende codes te schrijven.

Test de film en je ziet de drie berichten tegelijkertijd worden getraceerd, en een laatste bericht dat aangeeft dat het parallelle commando is voltooid:

  • 1e van 3
  • 2e van 3
  • 3e van 3
  • alle commando's zijn voltooid

Hoe zit het met het instellen van vertragingen binnen een parallelle opdracht? Eenvoudig. Wijzig de constructorfunctie van uw documentklasse als volgt:

 openbare functie ParallelTracing () var parallelCommand: Command = new ParallelCommand (0, nieuwe TraceCommand (0, "first wave, 1st of 2"), nieuwe TraceCommand (0, "first wave, 2nd of 2"), nieuwe TraceCommand (1 , "tweede golf, 1e van 3"), nieuwe TraceCommand (1, "tweede golf, 2e van 3"), nieuwe TraceCommand (1, "tweede golf, 3e van 3"), nieuwe TraceCommand (2, "laatste golf, 1ste van 2 "), nieuwe TraceCommand (2," laatste golf, 2e van 2 ")); parallelCommand.addEventListener (Event.COMPLETE, onCommandComplete); parallelCommand.start (); 

Test de film en u ziet de volgende drie berichtengolven worden afgedrukt, met een tijdsverschil van één seconde tussen elke golf:

  • eerste golf, 1e van 2
  • eerste golf, 2e van 2


  • tweede golf, 1e van 3
  • tweede golf, 2e van 3
  • tweede golf, derde van 3


  • laatste golf, 1e van 2
  • laatste golf, 2e van 2

Om een ​​beter idee te krijgen van wat er gaande is, bekijk deze illustratie:


Serieel commando

Het tweede type samengestelde opdracht is het seriële commando. Een seriële opdracht voert de subopdrachten achter elkaar uit, oftewel in reeksen. De tweede opdracht wordt bijvoorbeeld uitgevoerd na de voltooiing van de eerste en de derde wordt uitgevoerd na de voltooiing van de tweede opdracht. De volgende afbeelding geeft een visueel concept van een serieel commando:


De SerialCommand-klasse

Hier is de broncode voor de SerialCommand-klasse. De methode overschreven execute () roept de methode start () van het eerste subopdracht aan en luistert naar de gebeurtenis COMPLETE. Vervolgens start de gebeurtenislistener het volgende subopdracht en luistert naar de COMPLETE-gebeurtenis, enzovoort, totdat alle subopdrachten zijn voltooid. Op dat moment wordt de COMPLETE gebeurtenis voor de hele Serial Commando verzonden.

 pakketopdrachten import flash.events.Event; public class SerialCommand breidt Command uit private var _commands: Array; openbare functie SerialCommand (delay: Number ,? commands) super (delay); _commands = opdrachten;  private var _completeCommandCount: int; override final protected function execute (): void // stel het volledige aantal opdrachten in op nul _completeCommandCount = 0; // luister naar de complete gebeurtenis van de eerste subopdracht? _commands [0] .addEventListener (Event.COMPLETE, onSubcommandComplete); //? en start het subcommando _commands [0] .start ();  private function onSubcommandComplete (e: Event): void // stop listening for the complete event Command (e.target) .removeEventListener (Event.COMPLETE, onSubcommandComplete); // verhoog het volledige aantal opdrachten _completeCommandCount ++; // als alle opdrachten voltooid zijn? if (_completeCommandCount == _commands.length) //? dan is dit seriële commando compleet ();  else //? anders luisteren naar de complete gebeurtenis van de volgende subopdracht? _commands [_completeCommandCount] .addEventListener (Event.COMPLETE, onSubcommandComplete); //? en start het subcommando _commands [_completeCommandCount] .start (); 

Voorbeeld: seriële tracering

Laten we de SerialCommand-klasse gebruiken voor een seriële tracering. Maak net zoals eerder een nieuw Flash-document, kopieer de map "commands" over en schrijf een nieuwe documentklasse:

 pakket import commands.Command; importeer commando's.SerialCommand; importeer commando's. TikCommand; import flash.display.Sprite; import flash.events.Event; public class SerialTracing breidt uit met Sprite public function SerialTracing () var serialCommand: Command = new SerialCommand (0, new TraceCommand (0, "first command"), nieuwe TraceCommand (1, "second command"), nieuwe TraceCommand (1, " derde commando ")); serialCommand.addEventListener (Event.COMPLETE, onCommandComplete); serialCommand.start ();  private function onCommandComplete (e: Event): void trace ("alle opdrachten zijn voltooid"); 

Test de film en de volgende berichten worden één voor één getraceerd, met een interval van één seconde, gevolgd door "alle opdrachten zijn voltooid".

  • eerste commando


  • tweede commando


  • derde commando

Hier is een conceptfiguur van dit voorbeeld die u helpt een beter begrip te krijgen van wat er gaande is.


Geneste samengestelde opdrachten

Tot nu toe hebben we alleen het meest elementaire gebruik van parallelle en seriële commando's verkend, en het lijkt geen zin om ze te gebruiken in plaats van afzonderlijke commando's. Er zijn echter momenten waarop u veel meer complexe opdrachten moet uitvoeren en u kunt meerdere samengestelde opdrachten combineren om geneste opdrachten te maken die aan uw behoeften voldoen. Het volgende voorbeeld laat zien hoe u de klassen ParallelCommand en SerialCommand gebruikt om dergelijke geneste opdrachten te maken.


Voorbeeld: geneste commando's

Maak net zoals eerder een nieuw Flash-document, kopieer de map "commands" over en schrijf een nieuwe documentklasse:

 pakket import commands.Command; importeer commando's. ParallelCommand; importeer commando's.SerialCommand; importeer commando's. TikCommand; import flash.display.Sprite; import flash.events.Event; public class NestedCommands breidt Sprite uit openbare functie NestedCommands () var nestedCommands: Command = new SerialCommand (0, new ParallelCommand (0, new TraceCommand (0, "parallelle opdracht # 1, part 1 of 2"), nieuwe TraceCommand (0, "parallel commando # 1, deel 2 van 2"), nieuwe TraceCommand (0, "------------------------------- - ")), nieuwe ParallelCommand (1, nieuwe TraceCommand (0," parallelle opdracht # 2, deel 1 van 3 "), nieuwe TraceCommand (0," parallelle opdracht # 2, deel 2 van 3 "), nieuwe TraceCommand (0 , "parallel commando # 2, deel 3 van 3"), nieuwe TraceCommand (0, "------------------------------ - ")), nieuwe ParallelCommand (1, nieuwe TraceCommand (0," last command "), nieuwe TraceCommand (0," ---------------------- ---------- "))); nestedCommands.addEventListener (Event.COMPLETE, onCommandComplete); nestedCommands.start ();  private function onCommandComplete (e: Event): void trace ("alle opdrachten zijn voltooid"); 

Test de film en het programma zal het volgende bericht chunks één voor één, met een tijdsverschil van één seconde afdrukken. Net als in de vorige voorbeelden wordt een laatste volledig bericht afgedrukt wanneer alle subopdrachten compleet zijn.

  • parallelle opdracht # 1, deel 1 van 2
  • parallelle opdracht # 1, deel 2 van 2
  • --------------------------------


  • parallelle opdracht # 2, deel 1 van 3
  • parallelle opdracht # 2, deel 2 van 3
  • parallelle opdracht # 2, deel 3 van 3
  • --------------------------------


  • laatste commando
  • --------------------------------

Hier is de concept figuur van dit voorbeeld.


Voorbeeld: lichtcircuit

Laten we tot slot een meer praktisch voorbeeld bekijken. We gebruiken het opdrachtraamwerk dat we hebben gebouwd om een ​​demo met een lichtcircuit te maken, met geavanceerde timing. Voordat we beginnen, (u raadt het al) maakt u een nieuw Flash-document, kopieert u de map "commands" en maakt u een nieuwe documentklasse.


Stap 1: Het lichtsymbool

Maak een filmclipsymbool, met een tijdlijnanimatie waarbij een cirkel de kleur van grijs in geel verandert.

Voeg in de tijdlijn bij het laatste hoofdframe de volgende code toe. Hierdoor stopt de filmclip met animeren en verzendt u een COMPLETE-gebeurtenis:

 hou op(); dispatchEvent (nieuw evenement (Event.COMPLETE));

Als u codering op de tijdlijn wilt vermijden, kunt u een klasse maken voor uw lichte filmclip, met een functie:

 publieke functie bereiktEndOfAnimation (): void stop (); dispatchEvent (nieuw evenement (Event.COMPLETE)); 

? en schrijf dan het volgende in de constructor voor die klasse:

 addFrameScript (4, reached EndOfAnimation) // waarbij 4 één is minder dan het aantal frames

Stap 2: Het circuit

Leg lichte instanties op het podium en benoem ze zoals de volgende afbeelding laat zien:


Stap 3: interactie

Sleep een component Button vanaf het componentenpaneel naar het werkgebied en noem deze "start_btn". We willen onze opdrachten uitvoeren als op deze knop wordt gedrukt.


Stap 4: Indicator voltooiing

Maak een tekstveld op het werkgebied en typ uw voltooiingsbericht in. Converteer het vervolgens naar een filmclipsymbool en noem het exemplaar "completeMessage_mc".


Stap 5: De documentklasse

Nu is het tijd om de documentklasse te bewerken. Declareer een private variabele "circuitCommand", die zal worden gebruikt om een ​​verwijzing naar een Command-object vast te houden:

 privé var circuitCommand: Command;

Aan het begin van het programma moeten alle lichten worden uitgeschakeld, dat wil zeggen gestopt bij het eerste frame en het voltooiingsbericht moet worden verborgen. Daarom noemen we de methode reset () in de constructor.

 reset ();

Maak vervolgens onze geneste commando's die de animaties van de lichte filmfragmenten afspelen, waarbij ze worden belicht met de juiste timing. We gebruiken hier een PlayCommand-klasse, die gewoon de methode play () van een filmclip aanroept. We zullen de klas later schrijven.

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

Luister vervolgens naar de COMPLETE gebeurtenis van de opdracht en de KLIK-gebeurtenis van de startknop:

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

Stap 6: Event-handlers toevoegen

Toon het voltooiingsbericht wanneer de opdracht is voltooid:

 private function onCommandComplete (e: Event): void completeMessage_mc.visible = true; 

Reset het circuit en start het commando wanneer op de startknop wordt geklikt.

 persoonlijke functie startCircuit (e: MouseEvent): void reset (); circuitCommand.start (); 

Stap 7: De resetmethode

Het laatste deel voor de documentklasse is de methode reset (). Niets te maken met opdrachten hier.

 persoonlijke functie 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); 

Stap 8: De PlayCommand-klasse

Het laatste deel van dit voorbeeld is de PlayCommand-klasse. Zoals eerder vermeld, is het eenvoudig om de methode play () van een filmclip aan te roepen. Zodra de methode play () wordt aangeroepen in de methode exemplaar () van de opdracht overschreven (), wordt de methode complete () ook genoemd.

 pakketopdrachten import flash.display.MovieClip; import flash.events.Event; public class PlayCommand breidt Command uit private var _movieClip: MovieClip; openbare functie PlayCommand (delay: Number, movieClip: MovieClip) super (delay); _movieClip = filmClip;  override protected function execute (): void _movieClip.addEventListener (Event.COMPLETE, complet); _movieClip.play (); 

Sla dit op als PlayCommand.as in de map "commands".


Stap 9: Test de film

Oké, we zijn klaar! Test nu de film en u zult zien dat de lichten van links naar rechts worden verlicht nadat op de startknop is geklikt. Het voltooiingsbericht wordt getoond wanneer alle lichten oplichten.

Dit is de visuele weergave van wat er in dit voorbeeld gebeurt:

Vergelijk het met de daadwerkelijke code en zie hoe gemakkelijk het is om te begrijpen:

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

Nogmaals, met de juiste code-inspringing, kan een complexe geneste opdracht worden uitgedrukt als eenvoudige en schone code.


Samenvatting

In deze tutorial heb je het concept van commando's geleerd. Instructies kunnen worden ingekapseld in opdrachten met identieke interfaces, net zoals elke knop op een afstandsbediening een andere actie heeft, maar de methode om elke actie op te roepen is hetzelfde: druk op de knop.

In deze zelfstudie hebt u ook twee soorten samengestelde opdrachten geïntroduceerd: parallel en serieel. Deze kunnen worden gebruikt om geneste commando's te maken die een geavanceerde timing van de uitvoering van de opdracht mogelijk maken, terwijl de code schoon blijft.


Conclusie

Het concept van commando's is erg handig en krachtig. Codering van codes is de belangrijkste manier om dingen eenvoudiger te maken tijdens het programmeren, en een van de meest gebruikte methoden is het gebruik van opdrachtobjecten. Ik hoop dat deze tutorial je helpt beter te begrijpen hoe je commando's moet gebruiken in praktische toepassingen.

In het volgende deel van deze zelfstudie laat ik u zien hoe u TweenLite kunt integreren met het opdrachtraamwerk dat we in deze zelfstudie hebben gemaakt. Vervolgens kunt u met eenvoudige en schone code overgangsovergangen afhandelen. Heel erg bedankt voor het lezen.