Håndtering Skjermarkitektur Den smertefri måte!

Noen gang trodde skjermarkitektur var en unødvendig smertefull og kjedelig oppgave? Da er denne opplæringen din venn.

Vi fant denne fantastiske forfatteren takket være FlashGameLicense.com, stedet å kjøpe og selge Flash-spill!


Endelig resultatforhåndsvisning

La oss se på det endelige resultatet vi vil jobbe for:


Trinn 1: Skjermprosessen

Hvis du er noe som jeg var, hatet jeg alltid starten på et prosjekt, fordi jeg måtte sette opp alle skjermene. Etter at jeg stoppet kodingen på tidslinjen, mistet jeg det enkle å bare si: gotoAndStop (x).

Som vi alle vet, er tidslinjekoding bare feil; Det forurenser miljøet og forårsaker tannråte. Det var imidlertid enkelt å bytte skjermer. Jeg brukte mye tid på nettet og prøvde å finne en effektiv metode for skjermveksling, men alt jeg fant var metoder som var fulle av smerte, straffer utvikleren for å ha komplekse skjermarkitekturer. Og ikke skiftende skjermer fra grunnskjermen førte til at jeg slakte stygg kode inn i spillet mitt, for eksempel:

 parent.parent.parent.dispatchEvent (Event.CUSTOM_EVENT, screen1_to_screen2);

Ser du hva jeg mener? Tilpasset arrangement etter tilpasset arrangement, ble jeg lei av denne absurditeten. Det må være en bedre måte.


Trinn 2: Lyset på enden av tunnelen

Så satte jeg meg for å finne en metode for å håndtere komplekse skjermarkitekturer uten alt det irriterende mentalt traume. Ingen hendelser. Jeg vendte meg til min favoritt måte å håndtere oppgaver som må refereres fra hvor som helst i spillet: Statiske variabler og metoder.

Ved å bruke statiske variabler kan jeg referere til et objekt fra hvor som helst jeg ønsket i spillet, selv i en popup av en popup av en popup. Jeg bestemte meg for å koble til dette med enkelheten og brukervennligheten til Flashs visningsliste.

Skriv inn ScreenHandler-klassen.


Trinn 3: Ditt spill

Det har sannsynligvis mange skjermer. Du har sannsynligvis din splash skjerm, hovedmeny, spill skjerm, kreditter, seier skjermen, og mange andre. Vi må sette opp våre skjermer først. Vi vil ikke legge noe inn i det ennå, spillet er opp til deg.

Her er skjermene jeg har:

Som du kan se, har jeg slått ut preloaderen. Preloading riktig er en helt annen opplæring. Du kan lære om det her:

Active Tuts +: Den omfattende veiledningen for å forhåndsinstallere en enkelt swf-fil

Jeg vil forklare hvordan du skal kombinere dette med den opplæringen nær slutten. Nå på den delen du har ventet på!


Trinn 4: ScreenHandler-klassen

I hovedsak er ScreenHandler-klassen et displayobjekt som holder alle skjermene dine og internt bytter dem til vilje. Koden er overraskende enkel. Imidlertid vil jeg ikke bare legge en kodemur for at du skal komme inn. Det ville være bortkastet hvis du ikke forstod koden helt. Så jeg vil bryte den ned i et par seksjoner.

Det første vi må gjøre er å lage den faktiske klassen. Her er koden:

 pakke import flash.display.Sprite; offentlig klasse ScreenHandler utvider Sprite // Variabler går her offentlig funksjon ScreenHandler () // Constructor går her // Funksjoner gå her

Wow, det er ekstremt tomt.

Neste legger vi til i våre skjermer som variabler:

 private var splashScreen: SplashScreen; privat var mainMenu: MainMenu; privat var levelVelg: LevelSelect; privat var spill: spill; private varemerker: Studiepoeng; privat var seier: seier;

Bare kast dem under "Variabler gå her" kommentar.

Og akkurat slik er vi 1/10 av veien der!


Trinn 5: Hva gjør det Tick

Dette er funksjonen du vil ringe for å bytte skjermene dine. Den gode nyheten er at det bare er 4 linjer med kode. Den dårlige nyheten er at det bare er fordi jeg liker å bryte ned koden min i håndterbare biter. Dette er den eneste offentlige funksjonen i hele klassen, da dette er alt du trenger å ringe for å få klassen til å fungere. Innkapsling på det fineste!

 public function switchTo (skjermnavn: streng): void newScreenName = screenName; switchScreens (); 

Det går under "Funksjoner gå her" kommentar. Enkelt, nei? Nå må du lage en variabel som heter newScreenName og en funksjon som heter switchScreens.

 private var newScreenName: String = "";

Du vet allerede hvor det går. Og her er switchScreens funksjonen:

 private funksjon switchScreens (): void removeOldScreen (); makeNewScreen (); 

Jeg advarte deg: håndterbare biter.


Trinn 6: Jeg vet fortsatt ikke noe!!!

Før du blir sint på meg, skjønner du at jeg gjør dette til ditt eget gode. Nei, egentlig. Å bryte den opp i håndterbare biter som dette gjør det lettere for deg å finne og endre koden hvis du trenger tilpasset funksjonalitet. Jeg finner alltid alltid behovet for å endre kode senere i spillet, så jeg har nettopp vedtatt denne kodingspraksis. Også, hvis du skriver kode og noe er ødelagt, er det lettere å finne kilden til problemet. Ok, nok av min sidetracking. Her er de funksjonene som får det til å skje (for ekte denne gangen).


Trinn 7: Skjønnheten til skjermlisten

FjernOldScreen-funksjonen tar sin mirakuløse funksjonalitet fra AS3s visningsliste. Dette var trolig den beste forbedringen fra AS2. Forholdet mellom foreldre og barn som visningslisten har, er ekstremt nyttig i nesten enhver visuell manipulasjon, og looping gjennom barn i et visningsobjekt er raskere enn å løpe gjennom MovieClips i en matrise. Det er virkelig flott. Før vi skriver removeOldScreen og makeNewScreen-funksjonene, trenger vi en forelder for å holde skjermene. Her er en annen variabel:

 private var screenLayer: Sprite = new Sprite ();

og legg til denne koden til konstruktøren din:

 this.addChild (screenLayer);

OK, nå har vi et foreldre fundament som gjør det enkelt å endre og feilsøke. Alt som er igjen å gjøre er å skrive deleteOldScreen-funksjonen. Her er koden:

 privat funksjon removeOldScreen (): void var oldScreen: MovieClip; oldScreen = screenLayer.getChildAt (0) som MovieClip; screenLayer.removeChild (oldScreen); 

Hva vi gjør er å skape en plassholdervariabel som skal bli vår nåværende skjerm. Vi tar da barnet på indeksen "0" (som er det første barnet til foreldreobjektet) og setter vår plassholder like i forhold til den. Denne praktiske metoden gjør det mulig for oss å gjøre hva vi liker til en hvilken som helst skjerm uten å måtte ringe skjermbildene bestemt variabelnavn. Vi bruker deretter removeChild-metoden for å kvitte seg med skjermen for godt. Helt nydelig.

Vel, nå kan vi lage en tom skjerm. Det ville være fint å kunne sette noe der, ikke sant? Vel, jeg skal fortell deg hvordan du gjør det.


Trinn 8: Korrigere den tomme skjermen

Dette er den mest verbose delen av koden, men det er veldig enkelt å lage, forstå og tilpasse. Denne delen av koden er i utgangspunktet en gigantisk bryteretning som inneholder alle skjermene dine. Argumentet om at vi passerer inn i bryterfunksjonen er at newScreenName-variabelen vi satte i bryterfunksjonen.

 privat funksjon makeNewScreen (): void switch (newScreenName) case "SplashScreen": splashScreen = ny SplashScreen (); screenLayer.addChild (av velkomst); gå i stykker; tilfelle "MainMenu": mainMenu = new MainMenu (); screenLayer.addChild (MainMenu); gå i stykker; tilfelle "LevelSelect": levelSelect = new LevelSelect (); screenLayer.addChild (levelSelect); gå i stykker; tilfelle "spill": spill = nytt spill (); screenLayer.addChild (spill); gå i stykker; tilfelle "Kreditt": Kreditt = Ny Kreditt (); screenLayer.addChild (sp); gå i stykker; sak "seier": seier = ny seier (); screenLayer.addChild (seier); gå i stykker; standard: mainMenu = new MainMenu (); screenLayer.addChild (MainMenu); gå i stykker;  newScreenName = ""; 

Koden er ganske selvforklarende, men jeg vil forklare det uansett.

 sak "Skjerm": skjerm = ny skjerm (); screenLayer.addChild (skjerm); gå i stykker;

Du knytter en streng til en skjerm. Den strengen er argumentet om at du vil passere inn i bryteren til funksjonen. Det går da gjennom bryteroppstillingen og velger riktig skjerm for å legge til. Den konstruerer deretter en forekomst av variabelen og legger den til skjermlageren. Du er ikke pålagt å angi en standard, men det er nyttig å ha en standard for eventuelle bryteretninger du har for feilsøkingsformål. Den aktiveres hvis ingen av de andre tilfellene stemmer overens med argumentet.

Merk: Registreringsstedet på skjermbildene må være øverst til venstre for skjermene som skal vises riktig.

Nå har vi funksjonaliteten bak ScreenHandler-klassen. Nå er det på tide å bruke det til vårt program! Før vi bruker det til vårt program, må vi legge til et barn på skjermlaget ellers, vi har ingenting å fjerne når vi ringer removeOldScreen første gang. Dette vil gi oss en feil, og feilene er dårlige. mkay?

 splashScreen = ny SplashScreen (); screenLayer.addChild (av velkomst);

Legg det under resten av konstruktøren. Nå går du til toppen av klassen og importerer flash.display.MovieClip, hvis du ikke allerede har gjort det, og vi kan fortsette.


Trinn 9: Gjør det til å fungere

Hvis du ikke har sett på opplæringen jeg refererte tidligere, kan det være på tide å gjøre det.

Active Tuts +: Den omfattende veiledningen for å forhåndsinstallere en enkelt swf-fil

Tilbake? Flott.

Skjermbehandleren vil bli lagt til applikasjonsklassen. Selve sprite selv vil være en offentlig statisk variabel, så du kan referere den fra hvor som helst i koden din, og den vil bytte skjerm. Lett, rett?

 offentlige statiske var-skjermer: ScreenHandler = ny ScreenHandler ();

Legg deretter til dette i applikasjonsklassens konstruktør:

 this.addChild (skjermer);

Hvis du trenger å bytte skjermbilder fra hvor som helst i koden din, gjør du det slik:

 Application.screens.switchTo ( "SelectedScreen");

Trinn 10: Det er mer?

Vel, vi er ferdig med skjermhandleren i seg selv. Etter at jeg kodes alle knappene for å bytte til hvilken skjerm jeg ønsker, virker den.

Du kan si: "Thomas, denne skjermen bytter er stygg! Jeg vil ha skjermoverganger!"

Vel, det er bra at kodene er lett tilpassbare. Bare spør pent neste gang.


Trinn 11: Gjør det bra

Det første trinnet i å legge til skjermoverganger, er å avgjøre hvilken type skjermovergang du vil ha. For dette eksempelet kommer jeg bare til å gjøre en enkel fade ut og inn. Enkel rett?

  • Start med å lage et nytt symbol.
  • Navngi den Overgang, og eksporter den for actionscript.
  • Tegn et rektangel på størrelsen på skjermen.
  • Lag en ny keyframe på ramme 10.
  • Lag en ny keyframe på ramme 20.
  • Gå tilbake til ramme en og konverter alfa til 0;
  • Gå til ramme 20 og konverter alfa til 0;
  • Høyreklikk på mellomrommet mellom keyframes og velg 'Create Shape Tween'.

Din ferdige skjermovergang skal se slik ut:

Nå som vi har satt opp, kan vi kode vår overgangsklasse!


Trinn 12: En liten klasse

Dette er en enkel klasse å sette opp for våre formål, selv om du alltid kan tilpasse det for å fikse dine behov. Det må utvide MovieClip, og det eneste vi legger til er en variabel.

 pakke import flash.display.MovieClip; importere flash.events.Event; offentlig klasse Overgang utvider MovieClip offentlig statisk var exitFrames: Number = 11; privat var-timer: tall = 0; offentlig funksjon ScreenTransition () this.addEventListener (Event.ENTER_FRAME, fjern); this.addEventListener (Event.REMOVED_FROM_STAGE, removeListeners);  privat funksjon fjern (e: hendelse): void timer ++; hvis (timer> = 20) parent.removeChild (dette);  privat funksjon removeListeners (e: Event): void this.removeEventListener (Event.ENTER_FRAME, fjern); this.removeEventListener (Event.REMOVED_FROM_STAGE, removeListeners); 

Variabelen vi la til var exitFrames. Vi satte det til 11. Hvorfor? Fordi det er rammen som overgangen når 100% alfa, og det er rammen vi skal bytte på skjermene på. De andre funksjonene håndterer fjerningen av selve klippet og håndterer fjerning av hendelseslyttere når den er fjernet. Mindre søppelsamling, eh?


Trinn 13: Men du sa ingen hendelser!

Husk hvordan jeg sa at vi ikke ville bruke hendelser? Vel, jeg løy. Skjermovergangen krever noen hendelser, slik at skiftingen av skjermen forsinkes, og overgangen fjernes etter at jobben er ferdig.

Siden begynnelsen var målet mitt å gjøre denne klassen så allsidig og enkel å bruke som mulig. Jeg ville ikke ha noen hodepine da jeg satte opp skjermarkitekturen min. I tråd med disse retningslinjene vil jeg legge til skjermoverganger et alternativ, siden noen ganger er det ikke nødvendig med en skjermovergang.


Trinn 14: Bytte ting rundt

For å legge til i skjermoverganger, trenger vi ikke engang å trykke på deleteOldScreen eller makeNewScreen-koden fordi jeg separerte dem på forhånd. Det er nesten som jeg visste at dette skulle skje ...

Vi kommer til å trenge en rekke nye variabler:

 private var transitionLayer: Sprite = new Sprite (); privat var overgang: Overgang; privat var transTimer: tall = 0; private var makeTransition: boolsk;

Overgangslaget skal huske vårt overgangsklipp. På den måten forstyrrer det ikke vårt skjermlagers antall barn. Overgangstimeren skal brukes til timing av våre handlinger i tilfelle akkurat slik. Overgangsvariabelen kommer til å kontrollere om en skjermovergang vil bli brukt, det er opp til deg!

Deretter må vi også endre ting rundt i konstruktøren. Dette er hva din nye konstruktør skal se ut som:

 this.addChild (screenLayer); this.addChild (transitionLayer); splashScreen = ny SplashScreen (); screenLayer.addChild (av velkomst);

Og sist men ikke minst, gå til deg importere området og importere flash.events.Event. Deretter kan vi gjøre veien.


Trinn 15: Gjenoppretter bryteren til funksjonen

Jeg vil fortsatt holde denne funksjonen kort og søt, for ikke å komplisere sluttresultatet til brukeren. Encapsulation er flott, nei?

 offentlig funksjon switchTo (skjermnavn: String, trans: Boolean = true): void newScreenName = screenName; makeTransition = trans; this.addEventListener (Event.ENTER_FRAME, switchScreens); 

Det er mange nye ting her inne. I delen Argumenter la vi til trans, som er satt til true som standard. Dette betyr at med mindre du sier noe annet, blir det automatisk satt til å foreta en skjermovergang. Dette sparer deg for å måtte skrive ut "sant" hver gang du bytter skjerm. Vår makeTransition-variabel settes deretter til trans. Funksjonen switchScreens nå aksepterer et hendelsesargument, som fører oss til neste avsnitt.


Trinn 16: Gjenopprett switchScreens-funksjonen

La oss fokusere på koden for å gjøre skjermovergangsarbeidet først. Dette vil innebære en god mengde endring fra vår tidligere enkle kode.

 private funksjon switchScreens (e: Event): void transTimer ++; hvis (transTimer == 1 && transitionLayer.numChildren < 1) transition = new Transition(); transitionLayer.addChild(transition);  if(transTimer >= transition.exitFrames) removeOldScreen (); makeNewScreen (); transTimer = 0; this.removeEventListener (Event.ENTER_FRAME, switchScreens); 

La meg slå det ned:

 private funksjon switchScreens (e: Event): void transTimer ++; hvis (transTimer == 1 && transitionLayer.numChildren < 1) transition = new Transition(); transitionLayer.addChild(transition); 

Først legger vi til et hendelsesargument i funksjonen. Vi satte transTimer til å øke med en hver ramme. Hvis transTimer er lik en, og overgangslaget har ingen barn, legger vi til en overgang.

 hvis (transTimer == transition.exitFrames) removeOldScreen (); makeNewScreen (); transTimer = 0; this.removeEventListener (Event.ENTER_FRAME, switchScreens); 

Når transTimer når exitFrames vi satt tidligere, gjør vi skjermendringen skje. Fordi det er hva det handler om, ikke sant? Deretter tilbakestilles transTimer og fjerner deretter hendelseslytteren. Nå skifter det skjermene med en jevn skjermovergang!


Trinn 17: Gjenopprett switchScreen-funksjonen (del 2)

Vi vil nå ta imot muligheten for at du ikke vil ha en overgang på skjermen. Vi skal pakke inn alle våre nåværende switchScreens-kode i en if-setning:

 hvis (makeTransition) // Alle dine nåværende switchScreens-kode går her

Var det ikke så lett? Nå lager vi et annet avsnitt for når makeTransition ikke er sant:

 hvis (makeTransition) // Alle dine nåværende switchScreens kode går her else removeOldScreen (); makeNewScreen (); this.removeEventListener (Event.ENTER_FRAME, switchScreens); 

Og der har du det, en fullt funksjonell skjermhåndteringsklasse med abliliteten til å kontrollere tilsetning av skjermoverganger! Flotte greier.


Trinn 18: Full ScreenHandler Class

Slik ser den ferdige koden ut:

 pakke import flash.display.Sprite; importer flash.display.MovieClip; importere flash.events.Event; offentlig klasse ScreenHandler utvider Sprite private var splashScreen: SplashScreen; privat var mainMenu: MainMenu; privat var levelVelg: LevelSelect; privat var spill: spill; private varemerker: Studiepoeng; privat var seier: seier; private var newScreenName: String = ""; private var screenLayer: Sprite = new Sprite (); private var transitionLayer: Sprite = new Sprite (); privat var overgang: Overgang; privat var transTimer: tall = 0; private var makeTransition: boolsk; offentlig funksjon ScreenHandler () this.addChild (screenLayer); this.addChild (transitionLayer); splashScreen = ny SplashScreen (); screenLayer.addChild (av velkomst);  offentlig funksjon switchTo (skjermnavn: String, trans: Boolean = true): void newScreenName = screenName; makeTransition = trans; this.addEventListener (Event.ENTER_FRAME, switchScreens);  private funksjon switchScreens (e: Event): void if (makeTransition) transTimer ++; hvis (transTimer == 1 && transitionLayer.numChildren < 1) transition = new Transition(); transitionLayer.addChild(transition);  if(transTimer == transition.exitFrames) removeOldScreen(); makeNewScreen(); transTimer = 0; this.removeEventListener(Event.ENTER_FRAME, switchScreens);   else  removeOldScreen(); makeNewScreen(); this.removeEventListener(Event.ENTER_FRAME, switchScreens);   private function removeOldScreen():void var oldScreen:MovieClip; oldScreen = screenLayer.getChildAt(0) as MovieClip; screenLayer.removeChild(oldScreen);  private function makeNewScreen():void switch(newScreenName) case "SplashScreen": splashScreen = new SplashScreen(); screenLayer.addChild(splashScreen); break; case "MainMenu": mainMenu = new MainMenu(); screenLayer.addChild(mainMenu); break; case "LevelSelect": levelSelect = new LevelSelect(); screenLayer.addChild(levelSelect); break; case "Game": game = new Game(); screenLayer.addChild(game); break; case "Credits": credits = new Credits(); screenLayer.addChild(credits); break; case "Victory": victory = new Victory(); screenLayer.addChild(victory); break; default: mainMenu = new MainMenu(); screenLayer.addChild(mainMenu); break;  newScreenName = "";   

Slik implementerer du det i applikasjonsklassen:

 offentlige statiske var-skjermer: ScreenHandler = ny ScreenHandler ();

i applikasjonskonstruktøren, legg til

 this.addChild (skjermer);

og bruk denne funksjonen hvor som helst i koden din for å bytte skjermbilder:

 Application.screens.switchTo ( "SelectedScreen");

Hvis du ikke vil ha en skjermovergang:

 Application.screens.switchTo ("SelectedScreen", false);

Trinn 19: Ferdig produkt


Trinn 20: Nyt

Jeg tror jeg fullførte det jeg bestemte meg for å gjøre. Klassen er enkel å bruke og enda mer allsidig i å legge til skjermoverganger enn den gode ole-tidslinjen. Jeg håper du får litt bruk ut av denne klassen, og til og med forbedre den og gjøre den enda mer allsidig. Himmelen er grensen med skjermoverganger, og kanskje (sannsynligvis), kan du komme med forbedrede metoder for å håndtere skjermarkitektur: den smertefrie måten!


Konklusjon

Jeg håper du likte denne opplæringen, takk for å lese!