The Power of Finite State Machines: Konsept og Creation
Share
Del
17
Del
Dette Cyber mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.
Denne todelte opplæringen vil dekke skape et multi-state bil med endelig tilstandsmaskin La oss ta en titt på det endelige resultatet vi skal jobbe mot. Wikipedia definerer en FSM (Finite State Machine) som en matematisk abstraksjon noen ganger brukt til å designe digitale logikk eller dataprogrammer. Det er en atferd modell består av et begrenset antall tilstander, overganger mellom disse landene, og handlinger, i likhet med en flyt graf der man kan inspisere hvordan logikk går når visse vilkår er oppfylt. Den har begrenset internminne; en inngangsfunksjon som leser symboler i en sekvens, en om gangen, uten å gå bakover; og en utgangsfunksjon, som kan være i form av et brukergrensesnitt, når modellen er implementert. Driften av en FSM begynner fra en av statene (kalt en start tilstand), går gjennom overganger (avhengig av inngangene) til forskjellige stater, og kan ende i noen av de som er tilgjengelige - men bare et bestemt sett av tilstander markere en vellykket flyt av drift. I mine egne ord, er en FSM en enhet som brukes av utviklere for å lage objekter som har ulike atferd bestemmes av den nåværende tilstand de er i. Avhengig av input, kan objektet reagere og /eller overgang til en annen stat Et godt eksempel vil være en 1970 HK VP70Z maskinpistol, som har tre skytemoduser:. sikkerhetsstandarder, single shot, og semi-automatiske tre-round burst. Avhengig av gjeldende modus du har det satt til (stat), resultatet (output) er annerledes når du trykker på avtrekkeren (input) Verktøy:. Når konseptualisere en idé (multi-state objektet du ' nytt forsøk på å lage), er det best å bruke en stat Transition Tabell vite hva stater og tiltak for de landene du trenger å legge Det er på tide for å starte et nytt prosjekt. Med FlashDevelop, opprette et nytt AS3 prosjekt. For navnet, sette CarFSM. Klikk "Bla gjennom ..." og lagre den på ønsket sted. Gå inn i pakken sporet og skriv "com.activeTuts.fsm". Forsikre deg om at "Opprett katalog for prosjektet" er valgt og klikk "OK" for å avslutte. Når prosjektet er lagt i FlashDevelop, klikk på "View" og velg "Project Manager". Se "src" mappen? Høyreklikk det og velg "Utforsk". Når du har den mappen åpen, skal du se "com" mappen du opprettet tidligere. Åpne kildekode Jeg har tatt med denne opplæringen og dra "eiendeler" -mappen i "src"; pass på at du ikke slippe den inn i "com" -mappen. Deretter gå inn i kildekoden "com" -mappen og dra "bit101" -mappen i "com" -mappen inne "src". Du kan også laste ned minimalComps her hvis du foretrekker å få det rett fra kilden. Til slutt, bore ned inne i "com" -mappen (innen "src") hele veien inn "FSM" og dobbeltklikk Hoved .som. Dette skal nå være åpen inne FlashDevelop (forutsatt at du har FD som din standard .as forlengelse søknad) Vi vil starte med å vurdere de to statene av en enda mer enkelt eksempel:. MinimalComps menn Markerings La oss si at vi ønsker en avkrysningsboks som vil reflektere sin nåværende tilstand ved å endre etiketten. Nedenfor er overgangstabellen for Markerings. Nå for koden. Inne Main.as, en linje under klasse importen, legge til metadata vist nedenfor. Deretter går inne i init () metoden og sette markøren under der det står "entry point". Deretter legger en metode samtale simpleExample (). Neste, sørg for at du har markøren aktiv et sted inne i metodekallet, og trykk "CTRL + SHIFT + 1" nøkler. En fantastisk vil vise; plukke "Generer privat funksjon" og trykke "Enter" -tasten. Nå bare kopiere og lime inn koden under inni den nyopprettede metoden. Deretter satte markøren inne i ordet "boksen" og trykk "CTRL + SHIFT + 1" for å automatisk importere den nødvendige klassen. Når dette er gjort, trykk "CTRL + ENTER" for å kjøre programmet. Fra nå av, hvis du får noen feil, kan du sammenligne dine klasser med de jeg har tatt med kilde nedlasting. Anmeldelser Var avmerkingsboks: avmerkingsbokser = new avmerkingsbokser (dette, 240, 160, "falske", showValue); checkBox.scaleX = checkBox.scaleY = 2; funksjon showValue (e: Hendelses): void {avmerkingsbokser (e.target) .label = Boolean (e.target.selected) .toString (); } Du bør ha noe som ligner på det du ser ovenfor denne linjen. Det er dine to stater, på og av. Hver gang du klikker, bytter avkrysnings stater og også skifter etikett som en form for produksjon. På den virkelige "Car" FSM prosjektet. Kontroller at du har prosjektet satt til å kjøre i "debug" modus for å aktivere sporing () uttalelser Ok, la oss glemme forhåndsvisning på øverst på siden og starte bilen FSM fra scratch. I Main.as, markere init () metoden sammen med simpleExample () metoden og trykke "BACK" -tasten for å fjerne dem. Gå en linje ovenfor konstruktøren og legge variablene nedenfor. Anmeldelser private Var _past: Number; private Var _present: Number; private Var _tick: Number; private Var _car: Bil, private Var _initiatedTest1: Boolean, private Var _initiatedTest2: Boolean, private Var _initiatedTest3: Boolean, private Var _initiatedTest4: Boolean, private Div _initiatedTest5: Boolean, private Var _initiatedTest6: Boolean, private Var _finalActions: Boolean, private Var _counter: Antall = 0; Variablene _past, _present, _tick, og _counter vil alle bli brukt til tidsbestemt utførelse. Jeg skal forklare mer om det snart. Den _car variabel vil holde referanse for Car klasse som vil kapsle saksbehandlings Car FSM handlinger. Resten er boolske egenskaper som brukes for å utløse tidsbestemte handlinger. La oss arbeide på tidsbestemt utførelse. Legg inn koden under inne i konstruktøren Få markøren inne i ordet "update" og trykk "CTRL + SHIFT + 1" og velg "Generer hendelse handler". Når du tester programmet, vil du se en utskrift som ligner på "Start av konstruktør = 2.119 sekunder" (det kan være mindre hvis du har en raskere PC). Det er det samme som å dele verdien av getTimer () med 1000, men de sier multiplikasjon er raskere. La oss gå videre til oppdateringen () -metoden. . Nå, når du teste den på nytt, vil du merke en trace () uttalelse pop-out hvert sekund. Den _counter blir deretter tilbakestilt til hva overlapping det måtte opprettholde timing nøyaktighet. Prøv å bruke en annen verdi enn to sekunder, og kjøre den et par ganger til. Videre til Car klassen. Før du går videre, gå videre og fjern at hvis () uttalelse inne oppdateringen () -metoden Som jeg nevnte tidligere, vi begynner med en ny idé om å skape et multi-state bil. La oss si at vi bestemte oss for å ha en bil som kan slås av og på, også drevet fremover og kan gå tom for gass. Det ville gi oss fire ulike stater -. ON, OFF, DRIVE_FORWARD, og OUT_OF_FUEL Det aller første du må gjøre er å regne ut de ulike tilstander og tiltak for disse landene i en stat Transition Table. Du kan bruke en blyant og et blankt ark til raskt å notere ned alle statene og handlinger Bil objektet ville trenge. Se bildet nedenfor. Ha alltid en "update ()" metoden å ha sanntid kontroll over stater. Som forbruker et høyere beløp av drivstoff når du kjører enn når motoren er på tomgang park. Det er lett å si hvor hver stat skal svare for hvert av tiltakene. Det virker enkelt fordi vi (som menneske) alle tenker på objekter for å være i en stat eller en annen. Nå er vi klare til å kode klassen. Inne i konstruktør-metoden i Main. som går en linje før ENTER_FRAME arrangementet lytteren og legge koden under Nå siden det ikke er noen bil klasse, får du markøren inne i "Car" ord og trykk "CTRL + SHIFT + 1", velger du "Opprett ny klasse" og trykke "Enter" -tasten. Bruk den samme informasjonen som vist nedenfor. Klikk "OK" for å avslutte Du skal nå ha bilen klassen åpen i FlashDevelop Legg inn koden under én linje . ovenfor klassen konstruktør The Car er satt opp til å bare konsumere drivstoff 6 ganger per sekund. Dette er representert ved klasse konstant ONE_SIXTH_SECONDS. I tillegg har forbruket beløpet avhenger av om bilen er på tomgang eller kjører fremover. Vi vil bruke IDLE_FUEL_CONSUMPTION og DRIVE_FUEL_CONSUMPTION til disse formålene. De fire landene er representert ved Strenge konstanter med ENGINE_OFF satt som standard. _engineTimer Eiendommen vil bli brukt til å utløse consumeFuel () hver 1 /6 sekunder, men bare hvis staten er enten ENGINE_ON eller ENGINE_DRIVE_FORWARD. Til slutt _fuelSupply (som er hva consumeFuel () vil sakte ta bort) tar i verdien av _fuelCapacity for en full tank. La bilen konstruktør tom for nå. . Gå under den og legge ned oppdateringen () metoden vist nedenfor Vi må Main.as kaller denne metoden på hver ENTER_FRAME hendelsen bestått i tiden mellom rammer. Når kalt, det sjekker bilens nåværende tilstand og kjører den aktuelle handlingen. Hvis igjen alene, kan tilstands bare skje gjennom consumeFuel () som setter det å OUT_OF_FUEL når _fuelSupply renner ut. Merk: Handlinger som er på din State Transition Table vil alltid være offentlighet brukt som input kontroller. Dette gjelder enten du bruker Prosedyre FSM eller staten Pattern Legg inn koden under etter oppdateringen () metoden Akkurat som oppdateringen () metoden, _currentState kontrollert og den aktuelle handlingen er kjørt. Det forklarer seg ganske mye Det samme gjelder for å snu bilen av. Legg det neste Det blir veldig enkelt å lage metodene. Bare kopier og lim den forrige, så gjør noen endringer her og der Alltid gå tilbake til State Transition Table for å se hva som må til skje for hver stat når du ringer inndatametode du jobber for tiden med Legg inn koden under turnKeyOff () -metoden Denne metoden er privat siden bare Car trenger tilgang til det. Det kalles seks ganger per sekund fra oppdateringen () Sett inn koden neste etter driveForward () -metoden Nå ser du hvordan koden går som forklart tidligere i Klassevariabler delen Denne metoden er privat siden bare Car trenger tilgang til det Sett inn koden neste Metoden sjekker først for å se om bilen har en full tank. Hvis ja, forteller den deg den har en full tank og avslutter metoden. Hvis bilen ikke har en full tank på den annen side, går det gjennom det kjente tilfellet /bryter uttalelse og kjører riktig trace () uttalelse. Den siste bit av koden beregner hvor mye som forbrukes drivstoff og fylles bare det å holde en full tank. Den skriver da verdien av en full tank Denne metoden hadde overstyres siden bilen arver fra Sprite som igjen arver fra EventDispatcher. Alt den gjør er å returnere en streng uttalelse vist nedenfor. Legg det som siste utvei for bil klasse Så nå, når du kaller trace (_car) fra Main.as, i stedet for å få" [objekt Car] ", får du en uttalelse som" Bilen er for tiden med en drivstoff beløp på 1,00 gallon (e). " La oss gå tilbake til Main.as for testing. Sørg for å lagre arbeidet ditt før du går fremover Inside Hoved konstruktør, rett etter hvor du har lagt den ENTER_FRAME arrangementet lytteren. . Tast inn koden under På dette peke bilen vil utføre alle seks handlinger uten tid forfalle. Den ENTER_FRAME hendelsen har ikke startet ennå Neste, komme på innsiden av oppdateringen () -metoden rett under der _tick legges til _counter og lim inn koden vist neste Jeg vet det er mye kode, men igjen, det er selvforklarende. Kjør programmet og sjekke ut. Hvis du får feil, sørg for å sammenligne koden med klassene jeg har tatt med denne opplæringen. Prøv å endre _fuelCapacity i Bil og blandings opp metoder på noen eller alle av prøveseksjonene og kjøre den på nytt. Du vil se at koden er solid og dette prosedyre FSM er effektiv. Og det er det! Vi er ferdige. Vent et øyeblikk. Siden alt er vel, hvorfor ikke vi legge evnen til å kjøre bakover og turbo? Mens på det, kan vi like godt legge til animasjon og lyd. Nå, tenk bare hvor oppsvulmet Car klassen ville få hvis du gjør det gjør alle de tingene bilen gjør på toppen av siden. Vi ser på kanskje 2 000 linjer med kode - minst. LOL! Jeg vil nok si, Ya, sikker, jeg kan hacke det. Men koden blir veldig skjør og lett å bryte. Så det kan være en god idé å bruke en annen teknikk. Hvis FSM objektet har enkel atferd, for all del, bruk denne teknikken. Men hvis du har et komplekst objekt som kanskje trenger å legge til nye funksjoner i fremtiden. Kanskje til og med legge til noen flere stater - vel, det er der staten Mønster kommer i Si hei til "storebror" av Prosedyre FSM. Ved hjelp av denne Design Pattern vil gjøre statene lett å vedlikeholde og gjøre endringer i, men den beste delen -. Andre stater kan nå legges uten fare for å ødelegge koden Hvis du vil bruke dette mønsteret, vil vi igjen henvise til vår betrodde State Transition Table. Se trinn 4. Staten mønster består av tre deler. Først er staten Interface, dette vil inneholde alle de handlingene du ser i State Transition Table. I tillegg kan denne staten Interface også inneholde metoder som er felles for alle statlige klasser. For det andre statlige klasser som samsvarer for hver stat vist i State Transition Table. Og for det tredje, Statens Machine - som normalt er den konverterte Prosedyre FSM objekt (Car klasse). Når konvertert, vil bilen gi offentlige accessors og modifikatorer å tillate ekstern kontroll fra alle statlige klasser. Bilen vil delegere handlinger til det aktive State Klikk på "Vis" og velg "Project Manager". Innenfor "src", bore ned til du ser "FSM" -mappen. Høyreklikk det og velge "Legg til > Nytt grensesnitt ...". Deretter trykke "Enter" Name it "iState". Grensesnitt starter med "I" for navnekonvensjon Når FlashDevelop åpner klassen, legge koden under i det Dette iState grensesnittet vil bli gjennomført av alle de statlige klasser. Den siste funksjonen toString () har ingenting å gjøre med å kontrollere bilen, men alle de statlige klassene bruke den For mer info om grensesnitt, se AS3 101:. Introduksjon til grensesnitt. La oss begynne å legge de statlige klasser Følg samme prosedyre når du opprettet iState Interface men i stedet, velger du «Legg til ny klasse" Name it "EngineOff". For grensesnittsporet klikker legge til og skriv "iState", bør dette finner iState klasse fra innenfor samme mappe. I tillegg bør krysset for "generere grensesnittmetoder implementeringer" velges. Klikk "OK" for å fullføre. Den nye klassen kommer ut halvveis ferdig. Det skal se svært likt det viser nedenfor. Disse statlige klasser trenger ikke å forlenge Sprite siden alle medier eiendeler (andre del) vil bli lagt til og styres via bil. Statene vil bli instansiert gjennom Car klassen bestått seg som referanse. En to-veis sammensetning strukturen vil bli brukt til å tillate kommunikasjon mellom bilen og de statlige klasser Endre konstruktøren metode for å matche koden Nedenfor Jeg har tatt den _car variable over den modifiserte konstruktøren. Nå kan vi styre bilen klasse fra innenfor denne staten. La oss gå videre til grensesnittet metoden implementeringer. Få inne i turnKeyOff () -metoden. Sjekk din State Transition Table for å se hva som skjer her. Deretter sammenligne det med den prosessuelle turnKeyOff () metoden inne i bilen klasse. Husk, vi har fortsatt Car klassen i Prosedyre FSM. Når du ser kampen. Kopier handlingen for ENGINE_OFF staten i tomt metoden. Den turnKeyOff () metoden bør gjenspeile hva du ser nedenfor trace () uttalelse har blitt erstattet av print () som vil vi legge til Car klassen senere Nå går inne i turnKeyOn () -metoden og legge til koden oppført ved siden Sjekk det mot deg State Transition Bord og prosedyre turnKeyOn () metode for ENGINE_OFF staten for å se om det er den samme. Den changeState () metoden er delegert tilbake til bilen passerer i hentes tilstand det er behov for å endre til. Resten av metodene blir behandlet på samme måte. Kopier koden under og erstatte de tomme metoder med det driveForward () metoden gjør det samme som den prosessuelle driveForward () metoder med _currentState sett som ENGINE_OFF fylle bensin () ber bilen for å se om tanken ikke er full. Hvis ikke, vil bilen deretter fylle på med drivstoff. Du vil se hvordan disse to metodene fungerer når vi endrer Car klassen senere. Oppdateringen () metoden er fortsatt tom siden bilen ikke skal kjøre. toString () fungerer samme som bilens toString () metode. Dette fullfører EngineOff klassen. Før du oppretter resten av de andre statlige klasser, la oss endre Car klassen og konvertere den til sin egen stat Machine . Viktig: Lag et duplikat Bil klasse før du følger fremgangsmåten nedenfor. En tekst kopi ville nok, men sørg for å lagre det som referanse for senere. I stedet for å gå gjennom endringene punkt for punkt, bare kopiere koden under og lim og erstatte innholdet av din bil klasse med det. La oss gå over endringene. Starter på variabel definisjon. Du vil merke at de fire landene har endret type til iState og er ikke lenger statiske konstanter. Deretter kaller konstruktøren nå init () som igjen kaller initializeState (). Alle statlige klassene er instansiert gjennom denne metoden. Så kommer den lette delen, ingen flere bryter uttalelser. Bilen bare delegater handlingene til den nåværende tilstand. Se turnKeyOff () ned for å fylle bensin () consumeFuel () metoden måtte bli offentlig tilgang for EngineOn og EngineDriveForward Og da de to metodene vi brukte i EngineOff sin fylle bensin () -metoden. - hasFullTank () og refillWithFuel (). Under dem er de eksplisitte getters som gir tilgang for alle fire stater. Det kan virke som det er rart protokollen, men det er bare innkapsling på jobb. changeState () gjør akkurat det den sier, det forandrer _currentState. Igjen, etter streng regel av OOP, den _engineTimer eiendommen kan nås og endres gjennom disse to metodene: få engineTimer () og sette engineTimer () print () for nå vil bare passere String parameter til en trace () uttalelse.. Og så toString () metode For å forenkle etableringen av de tre andre klasser, komme på innsiden av bilen klasse fra innenfor initialize ( ) metode. Plasser markøren på innsiden av "EngineOn" ord og trykk "CTRL + SHIFT + 1" for å generere en melding. Velg "Opprett ny klasse" og trykk "Enter". Tilpass informasjonen som vist på bildet nedenfor og klikk på "OK". Dette ligner til trinn 16 da du opprettet EngineOff klasse. Bare denne gangen, brukte vi FD sin hurtigtaster. Også, vil du merke en refence til bilen objektet i konstruktør som ble vedtatt i ved oppretting.
. Vi vil starte med prosedyre FSM og fremgang i staten Pattern design mønster. Konsept og etableringen vil være vårt hovedfokus i denne første delen; Vi vil deretter gå inn i programmet og forlengelse under den andre delen
Endelig resultat Forhåndsvisning
Hva er en Finite State Machine?
Trinn 1:. Setup
Trinn 2:. Varm opp
[SWF (width = 500, height = 350, framerate = 60, bakgrunnsfarge = 0xFFFFFF)]
Trinn 3:. Saksbehandlings Car FSM
_present = getTimer ();. Trace ('Start av konstruktør =' + _present * 0,001 + 'sekunder \\ n'); _ forbi = _present; addEventListener (Event.ENTER_FRAME, oppdatering);
_present = GetTimer legge koden under inn i det (); _ tick = (_present - _past) * 0,001; ///konvertert til 1/1000 milliseconds_past = _present; _counter + = _tick; ///brukes til forsøk med tidsbestemt execution.if (_counter > = 2) //2 sekunder {_counter - = 2; trace (_counter + '2 sekunder');}
Trinn 4:. The Car Class
_car = ny bil;. addChild (_car);
Trinn 5:.. Bil Variabler
public static konst ONE_SIXTH_SECONDS: Number = 1/6; //6 ganger per secondprivate konst IDLE_FUEL_CONSUMPTION: Number = 0,0055; privat konst DRIVE_FUEL_CONSUMPTION: Number = 0,011; ///CAR STATESprivate statisk konst ENGINE_OFF: String = 'off'; private static konst ENGINE_ON: String = 'på', privat statisk konst ENGINE_DRIVE_FORWARD: String = 'forover'; private static konst ENGINE_OUT_OF_FUEL: String = 'tom for drivstoff'; private Var _currentState: String = ENGINE_OFF; privat Var _engineTimer: Antall = 0; privat Var _fullCapacity: Number = 1; privat Div _fuelSupply: Number = _fullCapacity; //i gallons
< hr>
Trinn 6: Metoder fra staten Transition Table
offentlig funksjon oppdateringen ($ tick: Number): void {switch (_currentState) {case ENGINE_OFF: //ingenting break; case ENGINE_ON: _engineTimer + = $ tick; //gassforbruk og spor uttalelse if (_engineTimer > = ONE_SIXTH_SECONDS) //6 ganger per sekund intervall {trace ('vm'); //du kan kommentere dette ut hvis du liker _engineTimer - = ONE_SIXTH_SECONDS; //0 + overlappe consumeFuel (IDLE_FUEL_CONSUMPTION); ///30 sekunder gassforsyning} break; case ENGINE_DRIVE_FORWARD: _engineTimer + = $ tick; if (_engineTimer > = ONE_SIXTH_SECONDS) {trace ('vroomm'); //du kan kommentere ut dette hvis du liker _engineTimer - = ONE_SIXTH_SECONDS; consumeFuel (DRIVE_FUEL_CONSUMPTION); ///15 sekunder gassforsyning} break; case ENGINE_OUT_OF_FUEL: //ingenting break; }}
Trinn 7:.. Slå bilen på
offentlig funksjon turnKeyOn (): void {trace ("forsøke å snu bilen på ..."); bryteren (_currentState) {case ENGINE_OFF: trace ("! Snu bilen på ... motoren kjører nå"); _currentState = ENGINE_ON; gå i stykker; case ENGINE_ON: trace ("motorens allerede kjører du ikke trenger å skru av tenningen!"); gå i stykker; case ENGINE_DRIVE_FORWARD: trace ("du kjører så ikke skru av tenningen!"); gå i stykker; case ENGINE_OUT_OF_FUEL: trace ("no drivstoff - bilen vil ikke starte, få litt drivstoff før noe Retur nøkkelen til av-stilling.."); gå i stykker; }}
Trinn 8:.. Slå bilen av
offentlig funksjon turnKeyOff (): void {trace ("forsøkt å skru bilen av ...."); bryteren (_currentState) {case ENGINE_OFF: trace ("Bilens allerede av, kan du ikke vri nøkkelen mot klokken lenger ..."); gå i stykker; case ENGINE_ON: trace ("klikk ... motoren er slått av fra park."); _currentState = ENGINE_OFF; gå i stykker; case ENGINE_DRIVE_FORWARD: trace ("nvrm ... klikk ... rulle til en stopp ... motoren er slått av."); _currentState = ENGINE_OFF; gå i stykker; case ENGINE_OUT_OF_FUEL: trace ("du allerede har gjort dette når drivstoff kjørte ut tidligere ..."); gå i stykker; }}
Trinn 9:. Kjøring Forward
offentlig funksjon driveForward ():.. void {trace ("forsøker å kjøre framover..."); bryteren (_currentState) {case ENGINE_OFF: trace ("klikk, endre utstyr for å drive gjør ikke noe ... bilen ikke er i gang, tilbake utstyret til å parkere ..."); gå i stykker; case ENGINE_ON: trace ("klikk, giring å kjøre ... nå skulle noe ..."); _currentState = ENGINE_DRIVE_FORWARD; gå i stykker; case ENGINE_DRIVE_FORWARD: trace ("allerede kjører - ikke nødvendig å endre noe ..."); gå i stykker; case ENGINE_OUT_OF_FUEL: trace ("klikk, endre utstyr for å kjøre vil ikke gjøre noe ... bilen har ingen drivstoff, tilbake utstyret til å parkere ..."); gå i stykker; }}
Trinn 10: Forbruker Fuel
privat funksjon consumeFuel ($ forbruk: Number):.. Void {if ((_fuelSupply - = $ forbruk) < = 0) {_fuelSupply = 0; trace ("Phit ... Phit - motoren har stanset, ikke mer drivstoff til å kjøre, tilbake utstyret til å parkere ..."); _currentState = ENGINE_OUT_OF_FUEL; }}
Trinn 11:. Tanking av Car
offentlig funksjon fylle bensin ():.. void {trace ("forsøker å fylle bensin ..."); if (_fuelSupply == 1) {trace ("ikke nødvendig å fylle bensin akkurat nå, er tanken full."); komme tilbake; } Switch (_currentState) {case ENGINE_OFF: trace ("å komme ut av bilen og ..."); gå i stykker; case ENGINE_ON: trace ("vri nøkkelen til av-stilling, komme seg ut av bilen og ..."); _currentState = ENGINE_OFF; gå i stykker; case ENGINE_DRIVE_FORWARD: trace ("giring fra stasjonen til park og vri om nøkkelen til av-stilling, komme seg ut av bilen og ..."); _currentState = ENGINE_OFF; gå i stykker; case ENGINE_OUT_OF_FUEL: trace ("vri nøkkelen til av-stillingen, komme seg ut av bilen og ..."); _currentState = ENGINE_OFF; gå i stykker; } Var neededSupply: Number = _fullCapacity - _fuelSupply; _fuelSupply + = neededSupply; trace ("fylle opp til" + _fuelSupply + "gallon (r) av drivstoff.");}
Trinn 12:. Ved hjelp av toString () for å hjelpe trace () Uttalelser
styre offentlig funksjon toString (). String {return "Bilen er for tiden" + _currentState + "med et drivstoff mengde" + _fuelSupply.toFixed (2) + "gallon (s). ";}
Trinn 13:. Stress Testing
///test 0_car.turnKeyOff (); trace (_car); _ car.driveForward (); trace (_car); _ car.turnKeyOn (); trace (_car);
_car.update (_tick);.. //test 1 etter 5 sekunder med å kjøre bilen og //bare hvis _initiatedTest1 har en verdi på false.if (_counter > = 5 & &! _initiatedTest1) {_initiatedTest1 = true; _car.reFuel (); _car.reFuel (); _car.driveForward (); _car.turnKeyOff (); _car.turnKeyOff (); _car.driveForward (); _car.turnKeyOn (); _car.driveForward (); trace (_car);} //test 2 etter 11 secondsif (_counter > = 11 & &! _initiatedTest2) {_initiatedTest2 = true; _car.turnKeyOff (); _car.turnKeyOn (); _car.driveForward (); trace (_car);} //test 3 etter 30 secondsif (_counter > = 30 & &! _initiatedTest3) {_initiatedTest3 = true; _car.turnKeyOn (); _car.turnKeyOff (); _car.turnKeyOn (); _car.driveForward (); _car.turnKeyOn (); _car.turnKeyOff (); _car.turnKeyOn (); trace (_car);} //test 4 etter 35 sekunder hvis (_counter > = 35 & &! _initiatedTest4) {_initiatedTest4 = true; _car.reFuel (); _car.reFuel (); trace (_car); _car.turnKeyOff (); _car.driveForward (); _car.turnKeyOff (); _car.turnKeyOff (); _car.turnKeyOn (); trace (_car);} //test 5 etter 42 sekunder hvis (_counter > = 42 & &! _initiatedTest5) {_initiatedTest5 = true; _car.driveForward (); trace (_car);} //test 6 etter 45 sekunder hvis (_counter > = 45 & &! _initiatedTest6) {_initiatedTest6 = true; _car.turnKeyOn (); _car.turnKeyOn (); _car.driveForward (); trace (_car);} ///stoppe bilen etter 60 secondsif (_counter > = 60 & &! _finalActions) {_finalActions = true; trace ('gått' + getTimer () /1000); _car.turnKeyOff (); trace (_car);}
Trinn 14:. Presenterer State Pattern
Trinn 15:. Begynnelsen konverterings
funksjon turnKeyOff ():.. Tomrommet; funksjon turnKeyOn (): void; funksjon driveForward () : void; funksjon fylle bensin (): void; funksjon oppdateringen ($ tick: Number): void; funksjon toString (): String;
Trinn 16:.. Den EngineOff Class
Pakke com.activeTuts.fsm {public class EngineOff implementerer iState {offentlig funksjon EngineOff () {} /* INTERFACE com.activeTuts.fsm.IState * /public funksjon turnKeyOff () : void {} offentlig funksjon turnKeyOn (): void {} offentlig funksjon driveForward (): void {} offentlig funksjon fylle bensin (): void {} offentlig funksjon oppdateringen ($ tick: Number): void {} offentlig funksjon toString (): String {}}}
Trinn 17:. Behandling våre EngineOff Class
private Var _car: bil, offentlig funksjon EngineOff ($ bil: bil). {_car = $ bil;}
offentlig funksjon turnKeyOff (). Void {_car.print ("Bilens allerede av, du kan ikke vri nøkkelen mot klokken lenger ...");..}
_car.print ("Slå bilen på ... motoren er nå i gang!"); _car.changeState (_car.getEngineOnState ());
offentlig funksjon driveForward (). Void {_car.print ("klikk, endre utstyr for å drive gjør ikke noe ... bilen ikke er i gang, tilbake giret til å parkere ... ");} offentlig funksjon fylle bensin (): void {if (_car.hasFullTank () == false) {_car.print (" å komme ut av bilen og legge til "+ Number (_car.refillWithFuel . ()) toFixed (2) + "gallon (r) av drivstoffet."); }} Offentlig funksjon oppdateringen ($ tick: Number): void {} offentlig funksjon toString (): String {return "off";}
Trinn 18: The Car State Machine
pakke com.activeTuts.fsm {import flash.display.Sprite; import flash.events.Event; public class Bil strekker Sprite {///CAR STATES //motoren av staten //motor på statlig //kjøretur stat //ingen gass tilstand public static konst ONE_SIXTH_SECONDS: Number = 1/6; //6 ganger per sekund public static konst IDLE_FUEL_CONSUMPTION: Number = .0055; public static konst DRIVE_FUEL_CONSUMPTION: Number = 0,011; private Var _engineOffState: iState; private Var _engineOnState: iState; private Var _engineDriveForwardState: iState; private Var _engineOutOfFuelState: iState; private Var _fuelCapacity: Number = 1; private Var _fuelSupply: Number = _fuelCapacity; //starter på en full tank (i liter) private Var _engineTimer: Antall = 0; private Var _currentState: iState; offentlig funksjon Car () {init (); } Private funksjon init (): void {initializeStates (); } Private funksjon initializeStates (): void {_engineOffState = new EngineOff (denne); _engineOnState = new EngineOn (denne); _engineDriveForwardState = new EngineDriveForward (denne); _engineOutOfFuelState = new EngineOutOfFuel (denne); _currentState = _engineOffState; //standardtilstanden} offentlig funksjon oppdateringen ($ tick: Number): void {_currentState.update ($ tick); } ///Bil funksjoner offentlig funksjon turnKeyOn (e: Hendelses = null): void {_currentState.turnKeyOn (); } Offentlig funksjon turnKeyOff (e: Hendelses = null): void {_currentState.turnKeyOff (); } Offentlig funksjon driveForward (e: Hendelses = null): void {_currentState.driveForward (); } Offentlig funksjon fylle bensin (e: Hendelses = null): void {_currentState.reFuel (); } Offentlig funksjon consumeFuel ($ forbruk: Number): void {if ((_fuelSupply - = $ forbruk) < = 0) {_fuelSupply = 0; print ("motoren har stanset, ikke mer drivstoff til å kjøre ..."); changeState (_engineOutOfFuelState); }} Offentlig funksjon refillWithFuel (): Antall {var neededSupply: Number = _fuelCapacity - _fuelSupply; _fuelSupply + = neededSupply; returnere neededSupply; } Offentlig funksjon hasFullTank (): Boolean {var fullTank: Boolean = _fuelCapacity == _fuelSupply? sant: false; if (fullTank) print ("ikke nødvendig å fylle bensin akkurat nå, er den tank full ..."); returnere fullTank; } Offentlig funksjon getEngineOffState (): iState {return _engineOffState; } //Eksplisitt, vet du at du kaller en metode offentlig funksjon getEngineOnState (): iState {return _engineOnState; } Offentlig funksjon getEngineOutOfFuelState (): iState {return _engineOutOfFuelState; } Offentlig funksjon getEngineDriveForwardState (): iState {return _engineDriveForwardState; } Offentlig funksjon changeState ($ tilstand: iState): void {_currentState = $ tilstand; } Offentlig funksjon får engineTimer (): Antall {return _engineTimer; } //Implisitt, som om du får tilgang til en offentlig variabel offentlig funksjon satt engineTimer ($ verdi: Number): void {_engineTimer = $ verdi; } Offentlig funksjon print ($ tekst: String): void {trace (tekst $); } Overstyre offentlig funksjon toString (): String {return 'Bilen er for øyeblikket' + _currentState + "med et drivstoff mengde '+ _fuelSupply +' gallon (er). '; }}}
Trinn 19:. Opprette de tre andre stater