L'architettura dello schermo mai pensata era un compito inutilmente doloroso e noioso? Allora questo tutorial è tuo amico.
Abbiamo trovato questo fantastico autore grazie a FlashGameLicense.com, il posto dove comprare e vendere giochi Flash!
Diamo un'occhiata al risultato finale su cui lavoreremo:
Se sei come me, ho sempre odiato l'inizio di un progetto, perché avrei dovuto impostare tutti gli schermi. Dopo aver interrotto la codifica sulla timeline, ho perso la facilità di dire semplicemente: gotoAndStop (x).
Come tutti sappiamo, la codifica della timeline è semplicemente sbagliata; Inquina l'ambiente e causa la carie. Tuttavia è stato semplice cambiare schermata. Ho passato molto tempo online cercando di trovare un metodo efficiente di commutazione dello schermo, ma tutto ciò che ho trovato erano metodi pieni di dolore, punendo lo sviluppatore per avere architetture di schermo complesse. E non cambiare schermata dalla schermata di base mi ha fatto schiaffeggiare codice brutto nel mio gioco come:
parent.parent.parent.dispatchEvent (Event.CUSTOM_EVENT, screen1_to_screen2);
Capito quello che intendo? Evento personalizzato dopo evento personalizzato, mi sono stancato di questa assurdità. Ci deve essere un modo migliore.
Quindi, ho deciso di trovare un metodo per gestire architetture di schermo complesse senza tutto quel fastidioso trauma mentale. Nessun evento Ho scelto il mio modo preferito di gestire le attività che devono essere referenziate da qualsiasi parte del gioco: variabili e metodi statici.
L'utilizzo di variabili statiche mi permetterebbe di fare riferimento a un oggetto da qualsiasi luogo volessi nel gioco, anche in un popup di una finestra popup. Ho deciso di accoppiarlo con la semplicità e l'usabilità della lista di visualizzazione di Flash.
Inserisci la classe ScreenHandler.
Probabilmente ha molti schermi. Probabilmente hai la schermata iniziale, il menu principale, la schermata di gioco, i crediti, la schermata della vittoria e molti altri. Dobbiamo prima impostare i nostri schermi. Non ci metteremo ancora dei contenuti, il gameplay spetta a te.
Ecco gli schermi che ho:
Come puoi vedere, ho omesso il preloader. Il precaricamento corretto è un altro tutorial completo. Puoi conoscerlo qui:
Active Tuts +: la guida completa per il precaricamento di un singolo file swf
Spiegherò come combinarlo con quel tutorial verso la fine. Ora alla parte che stavate aspettando!
In sostanza, la classe ScreenHandler è un oggetto di visualizzazione che contiene tutti gli schermi e li commuta internamente a piacimento. Il codice è sorprendentemente semplice. Tuttavia, non metterò solo un muro di codice in cui incorrere. Sarebbe uno spreco se non capissi completamente il codice. Quindi lo dividerò in un paio di sezioni.
La prima cosa che dobbiamo fare è creare la classe attuale. Ecco il codice:
pacchetto import flash.display.Sprite; public class ScreenHandler estende Sprite // Le variabili vanno qui public function ScreenHandler () // Il costruttore va qui // Le funzioni vanno qui
Wow, è estremamente vuoto.
Successivamente aggiungeremo nelle nostre schermate come variabili:
private var splashScreen: SplashScreen; private var mainMenu: MainMenu; private var levelSelect: LevelSelect; private var game: Game; crediti privati var: crediti; Vittoria privata var: vittoria;
Basta lanciare quelli sotto il commento "Variables go here".
E proprio così, siamo 1/10 del modo lì!
Questa è la funzione che chiamerai per cambiare schermo. La buona notizia è che sono solo 4 righe di codice. La cattiva notizia è che è solo perché mi piace abbattere il mio codice in blocchi gestibili. Questa è l'unica funzione pubblica nell'intera classe, in quanto è tutto ciò che devi chiamare per far funzionare la classe. Incapsulamento al suo meglio!
public function switchTo (screenName: String): void newScreenName = screenName; switchScreens ();
Questo va sotto il commento "Funzioni vai qui". Semplice, no? Ora è necessario creare una variabile denominata newScreenName e una funzione chiamata switchScreens.
private var newScreenName: String = "";
Sai già dove va. Ed ecco la funzione switchScreens:
private function switchScreens (): void removeOldScreen (); makeNewScreen ();
Ti avevo avvertito: pezzi gestibili.
Prima che ti arrabbi con me, renditi conto che lo sto facendo per il tuo bene. No davvero. Rompendo il tutto in blocchi gestibili come questo, è più facile per te trovare e modificare il codice se hai bisogno di funzionalità personalizzate. Io stesso trovo sempre la necessità di modificare il codice più avanti nel gioco, quindi ho appena adottato questa pratica di codifica. Inoltre, se stai scrivendo il codice e qualcosa è rotto, è più facile trovare la fonte del problema. Ok, abbastanza del mio sviamento. Ecco le funzioni che lo fanno accadere (per davvero questa volta).
La funzione removeOldScreen prende la sua funzionalità miracolosa dalla lista di visualizzazione di AS3. Questo è stato probabilmente il miglior miglioramento da AS2. La relazione genitore-figlio che l'elenco di visualizzazione ha è estremamente utile in quasi tutte le manipolazioni visive e il looping tra i bambini in un oggetto di visualizzazione è più rapido del looping di MovieClip in un array. È davvero fantastico Prima di scrivere le funzioni removeOldScreen e makeNewScreen, abbiamo bisogno di un genitore per tenere gli schermi. Ecco un'altra variabile:
private var screenLayer: Sprite = new Sprite ();
e aggiungi questa linea di codice al tuo costruttore:
this.addChild (screenLayer);
Bene, ora abbiamo un fondamento genitore che consente facili modifiche e debug. Tutto ciò che resta da fare è scrivere la funzione removeOldScreen. Ecco il codice:
private function removeOldScreen (): void var oldScreen: MovieClip; oldScreen = screenLayer.getChildAt (0) come MovieClip; screenLayer.removeChild (oldscreen);
Quello che stiamo facendo è creare una variabile segnaposto che diventerà la nostra schermata corrente. Quindi prendiamo il bambino all'indice di '0' (che è il primo figlio dell'oggetto genitore) e impostiamo il nostro segnaposto su di esso. Questo metodo conveniente ci consente di fare tutto ciò che ci piace su qualsiasi schermo senza dover chiamare il nome specifico della schermata. Quindi usiamo il metodo removeChild per sbarazzarci definitivamente dello schermo. Semplicemente bellissima.
Bene, ora possiamo creare uno schermo vuoto. Sarebbe bello poter mettere qualcosa lì, giusto? Bene, sto per dirti come farlo.
Questa è la sezione più dettagliata del codice, ma è molto facile da realizzare, capire e personalizzare. Questa sezione del codice è fondamentalmente una gigantesca istruzione switch che contiene tutti i tuoi schermi. L'argomento che passiamo alla funzione switch è la variabile newScreenName che impostiamo nella funzione switchTo.
funzione privata makeNewScreen (): void switch (newScreenName) case "SplashScreen": splashScreen = new SplashScreen (); screenLayer.addChild (splashScreen); rompere; case "MainMenu": mainMenu = new MainMenu (); screenLayer.addChild (mainMenu); rompere; caso "LevelSelect": levelSelect = new LevelSelect (); screenLayer.addChild (levelSelect); rompere; case "Game": game = new Game (); screenLayer.addChild (gioco); rompere; caso "Crediti": crediti = nuovi crediti (); screenLayer.addChild (crediti); rompere; caso "Vittoria": vittoria = nuova Vittoria (); screenLayer.addChild (vittoria); rompere; default: mainMenu = new MainMenu (); screenLayer.addChild (mainMenu); rompere; newScreenName = "";
Il codice è abbastanza auto-esplicativo, ma lo spiegherò comunque.
case "Screen": screen = new Screen (); screenLayer.addChild (schermo); rompere;
Si associa una stringa a uno schermo. Quella stringa è l'argomento che passerai nella funzione switchTo. Quindi passa attraverso l'istruzione switch e seleziona la schermata corretta da aggiungere. Quindi costruisce un'istanza della variabile e la aggiunge allo screenLayer. Non è necessario impostare un valore predefinito, ma è utile avere un valore predefinito per qualsiasi istruzione switch che si ha a scopo di debug. Si attiva se nessuno degli altri casi corrisponde all'argomento.
Nota: il punto di registrazione degli schermi deve essere nell'angolo in alto a sinistra affinché le schermate vengano visualizzate correttamente.
Ora abbiamo la funzionalità dietro la classe ScreenHandler. Ora è il momento di applicarlo al nostro programma! Prima di applicarlo al nostro programma, abbiamo bisogno di aggiungere un child allo screenLayer altrimenti, non avremo nulla da rimuovere quando chiamiamo removeOldScreen la prima volta. Questo ci darà un errore, e gli errori sono cattivi. Mkay?
splashScreen = new SplashScreen (); screenLayer.addChild (splashScreen);
Aggiungi quello sotto il resto del costruttore. Ora vai all'inizio della classe e importa flash.display.MovieClip, se non lo hai già fatto, e possiamo andare avanti.
Se non hai guardato il tutorial a cui ho fatto riferimento in precedenza, ora potrebbe essere il momento di farlo.
Active Tuts +: la guida completa per il precaricamento di un singolo file swf
Indietro? grande.
Il gestore dello schermo verrà aggiunto alla classe Application. Lo sprite vero e proprio sarà una variabile statica pubblica, quindi puoi fare riferimento da qualsiasi parte del tuo codice e cambierà lo schermo. Facile, giusto?
schermate statiche pubbliche var: ScreenHandler = new ScreenHandler ();
quindi aggiungi questo al costruttore della classe Application:
this.addChild (schermi);
Se hai mai bisogno di cambiare schermo da qualsiasi parte del tuo codice, ecco come lo fai:
Application.screens.switchTo ( "SelectedScreen");
Bene, abbiamo finito con il gestore dello schermo di per sé. Dopo aver codificato tutti i pulsanti per passare alla schermata desiderata, funziona.
Potresti dire: "Thomas, questo cambio di schermata è brutto! Voglio le transizioni dello schermo!"
Bene, è una buona cosa che i codici siano facilmente personalizzabili. Basta chiedere gentilmente la prossima volta.
Il primo passo nell'aggiunta delle transizioni dello schermo è decidere quale tipo di transizione dello schermo si desidera. Per questo esempio, farò una semplice dissolvenza in entrata. Facile?
La transizione dello schermo finita dovrebbe assomigliare a questa:
Ora che abbiamo impostato questo, lasciamo codificare la nostra classe di transizione!
Questa è una classe semplice da configurare per i nostri scopi, anche se puoi sempre personalizzarla per soddisfare le tue esigenze. Ha bisogno di estendere MovieClip e l'unica cosa che stiamo aggiungendo è una variabile.
package import flash.display.MovieClip; import flash.events.Event; public class Transition estende MovieClip public static var exitFrames: Number = 11; timer var privato: Number = 0; public function ScreenTransition () this.addEventListener (Event.ENTER_FRAME, remove); this.addEventListener (Event.REMOVED_FROM_STAGE, removeListeners); funzione privata remove (e: Event): void timer ++; if (timer> = 20) parent.removeChild (this); private function removeListeners (e: Event): void this.removeEventListener (Event.ENTER_FRAME, remove); this.removeEventListener (Event.REMOVED_FROM_STAGE, removeListeners);
La variabile che abbiamo aggiunto era exitFrames. Lo impostiamo su 11. Perché? Perché quello è il fotogramma che la transizione raggiunge il 100% di alpha, ed è il fotogramma su cui andremo ad accendere gli schermi. Le altre funzioni gestiscono la rimozione della clip stessa e gestiscono la rimozione dei listener di eventi una volta che sono stati rimossi. Meno raccolta rifiuti, eh?
Ricorda come ho detto che non avremmo usato gli eventi? Bene, ho mentito. La transizione dello schermo richiede alcuni eventi, in modo che il cambio dello schermo si ritardi correttamente e la transizione venga rimossa dopo che ha terminato il suo lavoro.
Fin dall'inizio, il mio obiettivo era rendere questa classe il più versatile e facile da usare possibile. Non volevo alcun mal di testa quando ho configurato l'architettura dello schermo. In linea con queste linee guida, renderò un'opzione l'aggiunta delle transizioni dello schermo, poiché a volte non è necessaria una transizione dello schermo.
Per aggiungere transizioni dello schermo, non dobbiamo nemmeno toccare il codice removeOldScreen o makeNewScreen perché li ho separati in precedenza. È quasi come se sapessi che questo sarebbe successo ...
Avremo bisogno di una sfilza di nuove variabili:
private var transitionLayer: Sprite = new Sprite (); transizione privata var: transizione; private var transTimer: Number = 0; private var makeTransition: Boolean;
Il transitionLayer ospiterà la nostra clip di transizione. In questo modo non interferisce con il numero di bambini del nostro screenLayer. Il timer di transizione verrà utilizzato per sincronizzare le nostre azioni nell'evento giusto. La variabile di transizione make controllerà se verrà utilizzata una transizione dello schermo, dipende da te!
Successivamente, avremo bisogno di cambiare le cose nel costruttore pure. Questo è come dovrebbe essere il tuo nuovo costruttore:
this.addChild (screenLayer); this.addChild (transitionLayer); splashScreen = new SplashScreen (); screenLayer.addChild (splashScreen);
E, ultimo ma non meno importante, vai alla tua area di importazione e importa flash.events.Event. Dopo di ciò possiamo fare strada.
Voglio comunque mantenere questa funzione breve e dolce, in modo da non complicare il risultato finale dell'utente. L'incapsulamento è fantastico, no?
public function switchTo (screenName: String, trans: Boolean = true): void newScreenName = screenName; makeTransition = trans; this.addEventListener (Event.ENTER_FRAME, switchScreens);
Ci sono molte nuove cose qui. Nella sezione degli argomenti, abbiamo aggiunto trans, che è impostato su true per impostazione predefinita. Ciò significa che, a meno che tu non dica diversamente, viene automaticamente impostato per eseguire una transizione dello schermo. Questo ti risparmia la fatica di dover digitare 'true' ogni volta che cambi schermo. La nostra variabile makeTransition è quindi impostata uguale a trans. La funzione switchScreens accetta ora un argomento evento, che ci conduce alla sezione successiva.
Concentriamoci sul codice per far funzionare la transizione dello schermo prima. Questo mostrerà una buona quantità di modifiche dal nostro codice semplice in precedenza.
funzione privata 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);
Lasciami scomporre:
funzione privata switchScreens (e: Event): void transTimer ++; if (transTimer == 1 && transitionLayer.numChildren < 1) transition = new Transition(); transitionLayer.addChild(transition);
Per prima cosa aggiungiamo un argomento Event nella funzione. Impostiamo il transTimer per aumentare di uno ogni fotogramma. Se transTimer è uguale a uno, e il transitionLayer non ha figli, aggiungiamo una transizione.
if (transTimer == transition.exitFrames) removeOldScreen (); makeNewScreen (); transTimer = 0; this.removeEventListener (Event.ENTER_FRAME, switchScreens);
Una volta che il transTimer raggiunge gli exitFrames impostati in precedenza, facciamo succedere il cambio di schermata. Perché è di questo che si tratta, giusto? Quindi reimposta il transTimer, quindi rimuove il listener di eventi. Ora cambia schermo con una transizione uniforme dello schermo!
Ora accetteremo la possibilità che non si desideri che avvenga una transizione dello schermo. Inseriremo tutto il codice corrente di switchScreens in una dichiarazione if:
if (makeTransition) // Tutto il tuo attuale codice switchScreens va qui
Non è stato facile? Ora creiamo un'altra sezione per quando makeTransition non è vero:
if (makeTransition) // Tutto il tuo attuale codice switchScreens va qui else removeOldScreen (); makeNewScreen (); this.removeEventListener (Event.ENTER_FRAME, switchScreens);
Ed ecco fatto, una classe di gestione dello schermo completamente funzionale con l'abilità di controllare l'aggiunta di transizioni dello schermo! Grandi cose.
Ecco come sarà il codice finito:
pacchetto import flash.display.Sprite; import flash.display.MovieClip; import flash.events.Event; public class ScreenHandler estende Sprite private var splashScreen: SplashScreen; private var mainMenu: MainMenu; private var levelSelect: LevelSelect; private var game: Game; crediti privati var: crediti; Vittoria privata var: vittoria; private var newScreenName: String = ""; private var screenLayer: Sprite = new Sprite (); private var transitionLayer: Sprite = new Sprite (); transizione privata var: transizione; private var transTimer: Number = 0; private var makeTransition: Boolean; public function ScreenHandler () this.addChild (screenLayer); this.addChild (transitionLayer); splashScreen = new SplashScreen (); screenLayer.addChild (splashScreen); public function switchTo (screenName: String, trans: Boolean = true): void newScreenName = screenName; makeTransition = trans; this.addEventListener (Event.ENTER_FRAME, switchScreens); funzione privata 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 = "";
Questo è come lo si implementa nella classe Application:
schermate statiche pubbliche var: ScreenHandler = new ScreenHandler ();
nel costruttore Applicazioni, aggiungi
this.addChild (schermi);
e usa questa funzione da qualsiasi parte del tuo codice per cambiare schermata:
Application.screens.switchTo ( "SelectedScreen");
Se non vuoi una transizione dello schermo:
Application.screens.switchTo ("SelectedScreen", false);
Credo di aver realizzato ciò che ho deciso di fare. La classe è facile da usare e ancora più versatile nell'aggiunta delle transizioni dello schermo rispetto alla timeline del buon vecchio. Spero che tu possa trarre qualche vantaggio da questa classe e persino migliorarla e renderla ancora più versatile. Il cielo è il limite con le transizioni dello schermo, e forse (probabilmente), puoi trovare metodi migliorati per gestire l'architettura dello schermo: il modo indolore!
Spero che questo tutorial ti sia piaciuto, grazie per la lettura!