Ooit gedacht dat de schermarchitectuur een onnodig pijnlijke en vervelende taak was? Dan is deze tutorial je vriend.
We vonden deze geweldige auteur dankzij FlashGameLicense.com, dé plek om Flash-spellen te kopen en verkopen!
Laten we eens kijken naar het eindresultaat waar we naartoe zullen werken:
Als je zoiets als ik was, had ik altijd een hekel aan het begin van een project, omdat ik alle schermen moest instellen. Nadat ik gestopt was met het coderen op de tijdlijn, verloor ik het gemak van alleen maar te zeggen: gotoAndStop (x).
Zoals we allemaal weten, is tijdlijncodering gewoon verkeerd; Het vervuilt het milieu en veroorzaakt tandbederf. Het was echter eenvoudig om van scherm te wisselen. Ik heb veel tijd besteed aan online zoeken naar een efficiënte methode voor schermomschakeling, maar het enige wat ik vond, waren methodes vol pijn, die de ontwikkelaar afzwoeren vanwege complexe schermarchitecturen. En het niet veranderen van schermen van het basisscherm zorgde ervoor dat ik lelijke code in mijn spel gooide, zoals:
parent.parent.parent.dispatchEvent (Event.CUSTOM_EVENT, screen1_to_screen2);
Zie je wat ik bedoel? Aangepaste gebeurtenis na aangepast evenement, ik werd deze absurditeit beu. Er moet een betere manier zijn.
Dus ik ging op zoek naar een methode om complexe schermarchitecturen te hanteren zonder al dat vervelende mentale trauma. Geen evenementen. Ik ging op mijn favoriete manier om met taken die overal in het spel moeten worden geraadpleegd: statische variabelen en methoden.
Door statische variabelen te gebruiken, kon ik naar een object verwijzen vanaf elke gewenste plek in het spel, zelfs in een pop-up van een pop-upvenster. Ik besloot dit te koppelen aan de eenvoud en bruikbaarheid van de weergavelijst van Flash.
Voer de klasse ScreenHandler in.
Het heeft waarschijnlijk veel schermen. Je hebt waarschijnlijk je startscherm, hoofdmenu, spelscherm, credits, overwinningsscherm en vele anderen. We moeten eerst onze schermen instellen. We zullen er nog geen inhoud in stoppen, de gameplay is aan jou.
Dit zijn de schermen die ik heb:
Zoals je ziet, heb ik de preloader weggelaten. Preloading correct is een hele andere tutorial. Je kunt hier meer over leren:
Active Tuts +: de uitgebreide handleiding voor het vooraf laden van een enkel SWF-bestand
Ik zal aan het einde uitleggen hoe je dit kunt combineren met die tutorial. Nu verder naar het gedeelte waar jullie allemaal op hebben gewacht!
In wezen is de ScreenHandler-klasse een weergaveobject dat al uw schermen bevat en deze naar believen intern schakelt. De code is verrassend eenvoudig. Ik zal echter niet alleen een muur van code leggen waar je tegen aan kunt lopen. Het zou zonde zijn als je de code niet volledig zou begrijpen. Dus ik zal het opsplitsen in een paar secties.
Het eerste dat we moeten doen is de eigenlijke klasse maken. Hier is de code:
pakket import flash.display.Sprite; public class ScreenHandler breidt Sprite uit // Variabelen gaan hier openbare functie ScreenHandler () // Constructor goes here // Functies ga hier
Wauw, dat is extreem leeg.
Vervolgens voegen we in onze schermen als variabelen toe:
privé var splashScreen: SplashScreen; private var mainMenu: MainMenu; privé var niveauSelecteer: LevelSelect; privé var-spel: Game; private var credits: Credits; privé var overwinning: Victory;
Werp die gewoon weg onder de opmerking 'Variabelen ga hier'.
En net als dat, we zijn 1 / 10e van de manier waarop daar!
Dit is de functie die u zult gebruiken om van scherm te wisselen. Het goede nieuws is dat het maar 4 regels code zijn. Het slechte nieuws is dat het alleen maar is omdat ik mijn code graag opsplits in hanteerbare brokken. Dit is de enige openbare functie in de hele klas, aangezien dit alles is dat je moet bellen om de klasse te laten functioneren. Inkapseling op zijn best!
public function switchTo (screenName: String): void newScreenName = screenName; switchScreens ();
Dat gaat onder de opmerking "Functies hier". Eenvoudig, niet? Nu moet je een variabele maken met de naam newScreenName en een functie met de naam switchScreens.
private var newScreenName: String = "";
Je weet al waar dat naartoe gaat. En hier is de functie SwitchScreens:
persoonlijke functie switchScreens (): void removeOldScreen (); makeNewScreen ();
Ik heb je gewaarschuwd: beheersbare brokken.
Voordat je boos op me wordt, besef dat ik dit doe voor je eigen bestwil. Nee echt. Door het op te splitsen in hanteerbare brokken als deze, wordt het voor u eenvoudiger om de code te vinden en aan te passen als u aangepaste functionaliteit nodig hebt. Zelf vind ik het altijd nodig om de code later in het spel te veranderen, dus heb ik deze codeermethode overgenomen. Als u code schrijft en er iets kapot is, is het gemakkelijker om de oorzaak van het probleem te vinden. Ok, genoeg van mijn zijspoor. Hier zijn de functies die het mogelijk maken (deze keer echt).
De functie removeOldScreen haalt zijn wonderbaarlijke functionaliteit uit de weergavelijst van AS3. Dit was waarschijnlijk de beste verbetering van AS2. De ouder-kindrelatie die in de weergavelijst staat is uiterst nuttig bij vrijwel elke visuele manipulatie en het doorlopen van de kinderen in een weergaveobject is sneller dan het doorlussen van MovieClips in een array. Het is echt geweldig. Voordat we de functies removeOldScreen en makeNewScreen schrijven, hebben we een ouder nodig om de schermen vast te houden. Hier is nog een variabele:
private var screenLayer: Sprite = new Sprite ();
en voeg deze regel code toe aan je constructor:
this.addChild (screenLayer);
Oke, nu hebben we een ouderstichting die eenvoudige aanpassingen en foutopsporing mogelijk maakt. U hoeft alleen nog de functie removeOldScreen te schrijven. Hier is de code:
private function removeOldScreen (): void var oldScreen: MovieClip; oldScreen = screenLayer.getChildAt (0) als MovieClip; screenLayer.removeChild (oldScreen);
Wat we doen, is het maken van een tijdelijke aanduiding variabele die ons huidige scherm 'zal worden'. We pakken het kind vervolgens bij de index van '0' (het eerste kind van het bovenliggende object) en stellen onze tijdelijke aanduiding gelijk aan. Met deze handige methode kunnen we doen wat we willen op elk scherm zonder de specifieke variabelenaam van het scherm te hoeven bellen. We gebruiken vervolgens de methode removeChild om voorgoed van het scherm af te komen. Gewoon mooi.
Welnu, nu kunnen we een leeg scherm maken. Het zou leuk zijn om daar iets neer te zetten, toch? Nou ik ga je vertellen hoe je dat moet doen.
Dit is het meest uitgebreide gedeelte van de code, maar het is heel gemakkelijk te maken, te begrijpen en aan te passen. Dit gedeelte van de code is eigenlijk een gigantisch switch-statement dat al je schermen bevat. Het argument dat we doorgeven aan de switch-functie is de variabele newScreenName die we in de functie switchTo hebben ingesteld.
private functie makeNewScreen (): void switch (newScreenName) case "SplashScreen": splashScreen = new SplashScreen (); screenLayer.addChild (Splashscreen); breken; case "MainMenu": mainMenu = new MainMenu (); screenLayer.addChild (Hoofdmenu); breken; case "LevelSelect": levelSelect = nieuwe LevelSelect (); screenLayer.addChild (levelSelect); breken; case "Game": game = nieuwe game (); screenLayer.addChild (spel); breken; case "Credits": credits = nieuwe Credits (); screenLayer.addChild (credits); breken; case "Victory": overwinning = nieuwe overwinning (); screenLayer.addChild (overwinning); breken; standaard: mainMenu = nieuwe MainMenu (); screenLayer.addChild (Hoofdmenu); breken; newScreenName = "";
De code is vrij duidelijk, maar ik zal het toch uitleggen.
case "Screen": scherm = nieuw scherm (); screenLayer.addChild (screen); breken;
U koppelt een string aan een scherm. Die string is het argument dat u doorgeeft aan de switchTo-functie. Vervolgens wordt de instructie switch doorlopen en wordt het juiste scherm geselecteerd om toe te voegen. Vervolgens wordt een instantie van de variabele geconstrueerd en toegevoegd aan de schermlaag. U hoeft geen standaard in te stellen, maar het is handig om een standaard te hebben voor elke switchinstructie die u hebt voor foutopsporingsdoeleinden. Het wordt geactiveerd als geen van de andere gevallen overeenkomt met het argument.
Opmerking: Het registratiepunt van de schermen moet in de linkerbovenhoek staan om de schermen correct weer te geven.
Nu hebben we de functionaliteit achter de klasse ScreenHandler. Nu is het tijd om het op ons programma toe te passen! Voordat we het op ons programma toepassen, moeten we een kind aan de schermlaag toevoegen, anders hebben we niets te verwijderen wanneer we de eerste keer removeOldScreen noemen. Dit geeft ons een foutmelding en fouten zijn slecht. mkay?
splashScreen = nieuw SplashScreen (); screenLayer.addChild (Splashscreen);
Voeg dat toe onder de rest van de constructor. Ga nu naar de top van de klas en import flash.display.MovieClip, als je dit nog niet hebt gedaan, en we kunnen verder gaan.
Als je niet hebt gekeken naar de tutorial die ik eerder heb genoemd, is dit misschien het moment om dit te doen.
Active Tuts +: de uitgebreide handleiding voor het vooraf laden van een enkel SWF-bestand
Terug? Super goed.
De schermhandler wordt toegevoegd aan de klasse Application. De eigenlijke sprite zelf zal een openbare statische variabele zijn, dus je kunt ernaar verwijzen vanaf elke plek in je code en het scherm veranderen. Makkelijk, toch?
openbare statische var-schermen: ScreenHandler = nieuwe ScreenHandler ();
Voeg dit dan toe aan de constructor van de Application class:
this.addChild (schermen);
Als u ooit ergens anders in uw code moet schakelen, doet u het als volgt:
Application.screens.switchTo ( "SelectedScreen");
Nou, we zijn klaar met de scherm-handler per se. Nadat ik alle knoppen heb gecodeerd om over te schakelen naar het scherm dat ik maar wil, werkt het.
Je zou kunnen zeggen: "Thomas, deze schermomschakeling is lelijk! Ik wil schermovergangen!"
Nou, het is maar goed dat de codes gemakkelijk kunnen worden aangepast. Vraag het de volgende keer gewoon lekker.
De eerste stap bij het toevoegen van schermovergangen is bepalen wat voor soort schermovergang u wilt. Voor dit voorbeeld ga ik eenvoudig een fade out en in maken. Eenvoudig in orde?
Uw voltooide schermovergang zou er als volgt uit moeten zien:
Nu we dat hebben ingesteld, kunnen we onze Transition-klasse coderen!
Dit is een eenvoudige les die u kunt instellen voor onze doeleinden, maar u kunt deze altijd aanpassen om aan uw behoeften te voldoen. Het moet MovieClip uitbreiden, en het enige dat we eraan toevoegen is een variabele.
pakket import flash.display.MovieClip; import flash.events.Event; public class Transition breidt MovieClip uit public static var exitFrames: Number = 11; privé var timer: Number = 0; openbare functie ScreenTransition () this.addEventListener (Event.ENTER_FRAME, remove); this.addEventListener (Event.REMOVED_FROM_STAGE, removeListeners); private function remove (e: Event): void timer ++; if (timer> = 20) parent.removeChild (this); private functie removeListeners (e: Event): void this.removeEventListener (Event.ENTER_FRAME, remove); this.removeEventListener (Event.REMOVED_FROM_STAGE, removeListeners);
De variabele die we hebben toegevoegd is exitFrames. We hebben het op 11 geplaatst. Waarom? Omdat dat het frame is dat de overgang 100% alfa bereikt, en dit is het frame waar we de schermen op zullen zetten. De andere functies behandelen het verwijderen van de clip zelf en behandelen het verwijderen van gebeurtenislisteners nadat deze zijn verwijderd. Minder garbage collection, eh?
Weet je nog hoe ik zei dat we geen evenementen zouden gebruiken? Wel, ik heb gelogen. De schermovergang vereist een aantal gebeurtenissen, zodat het schakelen van het scherm behoorlijk vertraagt en de overgang wordt verwijderd nadat de taak is voltooid.
Vanaf het begin was het mijn doel om deze klasse zo veelzijdig en gebruiksvriendelijk mogelijk te maken. Ik wilde geen hoofdpijn als ik mijn schermarchitectuur instelde. Om aan die richtlijnen te voldoen, zal ik het toevoegen van schermovergangen een optie maken, omdat soms een schermovergang niet nodig is.
Om schermovergangen toe te voegen hoeven we niet eens de removeOldScreen of makeNewScreen-code aan te raken omdat ik ze van tevoren heb gescheiden. Het is bijna alsof ik wist dat dit zou gaan gebeuren ...
We hebben een hoop nieuwe variabelen nodig:
private var transitionLayer: Sprite = new Sprite (); private var-overgang: overgang; private var transTimer: Number = 0; private var makeTransition: Boolean;
De transitionLayer gaat onze overgangsclip onderbrengen. Op die manier interfereert het niet met het aantal kinderen van onze ScreenLayer. De overgangstimer zal worden gebruikt om onze acties precies in het juiste geval te timen. De make-transitievariabele gaat bepalen of een schermovergang zal worden gebruikt, dat is aan jou!
Vervolgens moeten we ook de dingen veranderen in de constructor. Dit is hoe uw nieuwe constructeur eruit zou moeten zien:
this.addChild (screenLayer); this.addChild (transitionLayer); splashScreen = nieuw SplashScreen (); screenLayer.addChild (Splashscreen);
En last but not least, ga naar je importgebied en import flash.events.Event. Daarna kunnen we wijken.
Ik wil deze functie nog steeds kort en krachtig houden, om het eindresultaat van de gebruiker niet ingewikkeld te maken. Inkapseling is geweldig, nee?
public function switchTo (screenName: String, trans: Boolean = true): void newScreenName = screenName; makeTransition = trans; this.addEventListener (Event.ENTER_FRAME, switchScreens);
Er zitten hier veel nieuwe dingen in. In de sectie argumenten hebben we trans toegevoegd, die standaard is ingesteld op true. Dit betekent dat tenzij u iets anders zegt, het automatisch wordt ingesteld om een schermovergang te maken. Dit bespaart u de moeite van het typen van 'waar' telkens wanneer u van scherm wisselt. Onze makeTransition-variabele wordt dan gelijkgesteld aan trans. De functie SwitchScreens accepteert nu een gebeurtenisargument, dat ons naar de volgende sectie leidt.
Laten we ons concentreren op de code om de schermovergang eerst te laten werken. Dit zal een goede hoeveelheid verandering van onze eerder eenvoudige code kenmerken.
persoonlijke functie switchScreens (e: Event): void transTimer ++; if (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);
Laat me het afbreken:
persoonlijke functie switchScreens (e: Event): void transTimer ++; if (transTimer == 1 && transitionLayer.numChildren < 1) transition = new Transition(); transitionLayer.addChild(transition);
Eerst voegen we een gebeurtenisargument toe aan de functie. We hebben de transTimer met één frame verhoogd. Als de transTimer gelijk is aan één en de transitionLayer geen kinderen heeft, voegen we een overgang toe.
if (transTimer == transition.exitFrames) removeOldScreen (); makeNewScreen (); transTimer = 0; this.removeEventListener (Event.ENTER_FRAME, switchScreens);
Zodra de transTimer de exitFrames bereikt die we eerder hebben ingesteld, zorgen we ervoor dat het scherm verandert. Want dat is waar het allemaal om draait, toch? Vervolgens wordt de transTimer gereset en vervolgens de gebeurtenislistener verwijderd. Nu wisselt het van scherm met een vloeiende schermovergang!
We gaan nu tegemoet aan de mogelijkheid dat u geen schermovergang wilt laten plaatsvinden. We gaan al onze huidige switchScreen-code in een if-statement verwerken:
if (makeTransition) // Al uw huidige code voor SwitchScreens gaat hier
Was dat niet gemakkelijk? Nu maken we een andere sectie voor wanneer makeTransition niet waar is:
if (makeTransition) // Al uw huidige code voor SwitchScreens komt hier else removeOldScreen (); makeNewScreen (); this.removeEventListener (Event.ENTER_FRAME, switchScreens);
En daar heb je het, een volledig functionele schermverwerkingsklasse met de mogelijkheid om het toevoegen van schermovergangen te regelen! Goed spul.
Dit is hoe de voltooide code eruit zal zien:
pakket import flash.display.Sprite; import flash.display.MovieClip; import flash.events.Event; public class ScreenHandler breidt Sprite uit private var splashScreen: SplashScreen; private var mainMenu: MainMenu; privé var niveauSelecteer: LevelSelect; privé var-spel: Game; private var credits: Credits; privé var overwinning: Victory; private var newScreenName: String = ""; private var screenLayer: Sprite = new Sprite (); private var transitionLayer: Sprite = new Sprite (); private var-overgang: overgang; private var transTimer: Number = 0; private var makeTransition: Boolean; openbare functie ScreenHandler () this.addChild (screenLayer); this.addChild (transitionLayer); splashScreen = nieuw SplashScreen (); screenLayer.addChild (Splashscreen); publieke functie switchTo (screenName: String, trans: Boolean = true): void newScreenName = screenName; makeTransition = trans; this.addEventListener (Event.ENTER_FRAME, switchScreens); persoonlijke functie switchScreens (e: Event): void if (makeTransition) transTimer ++; if (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 = "";
Dit is hoe je het implementeert in de klasse Application:
openbare statische var-schermen: ScreenHandler = nieuwe ScreenHandler ();
in de constructor Applicaties, voeg toe
this.addChild (schermen);
en gebruik deze functie overal in uw code om van scherm te wisselen:
Application.screens.switchTo ( "SelectedScreen");
Als u geen schermtransitie wilt:
Application.screens.switchTo ("SelectedScreen", false);
Ik geloof dat ik heb bereikt wat ik van plan was te doen. De klasse is eenvoudig te gebruiken en nog veelzijdiger in het toevoegen van schermovergangen dan de tijdlijn van de goede ole. Ik hoop dat je deze klasse een beetje kunt gebruiken en zelfs kunt verbeteren en nog veelzijdiger kunt maken. De lucht is de limiet met schermovergangen, en misschien (waarschijnlijk) kun je komen met verbeterde methoden voor het hanteren van de schermarchitectuur: de pijnloze manier!
Ik hoop dat je deze tutorial leuk vond, bedankt voor het lezen!