Gestion de l’architecture de l’écran le moyen le plus simple

Vous avez déjà pensé que l’architecture d’écran était une tâche inutilement pénible et fastidieuse? Alors ce tutoriel est ton ami.

Nous avons trouvé cet auteur génial grâce à FlashGameLicense.com, le lieu d'achat et de vente de jeux Flash.!


Aperçu du résultat final

Jetons un coup d'œil au résultat final sur lequel nous allons travailler:


Étape 1: Le processus de sélection

Si vous êtes comme moi, j'ai toujours détesté le début d'un projet, car je devrais configurer tous les écrans. Après avoir arrêté de coder sur la timeline, j'ai perdu la facilité de simplement dire: gotoAndStop (x).

Comme nous le savons tous, le codage de la chronologie est tout simplement faux. Il pollue l'environnement et provoque la carie dentaire. Cependant, il était simple de changer d'écran. J'ai passé beaucoup de temps en ligne à essayer de trouver une méthode efficace de commutation d'écran, mais tout ce que j'ai trouvé, ce sont des méthodes pénibles, qui punissent le développeur d'avoir des architectures d'écran complexes. Et ne pas changer d'écran depuis l'écran de base m'a amené à insérer du code laid dans mon jeu, tel que:

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

Tu vois ce que je veux dire? Evénement personnalisé après événement personnalisé, je me suis lassé de cette absurdité. Il doit y avoir une meilleure façon.


Étape 2: La lumière au bout du tunnel

Je me suis donc mis à la recherche d'une méthode permettant de gérer des architectures d'écran complexes sans tout ce traumatisme mental gênant. Pas d'événements. Je me suis tourné vers ma manière préférée de gérer les tâches qui doivent être référencées à partir de n’importe où dans le jeu: variables statiques et méthodes..

L’utilisation de variables statiques me permettrait de référencer un objet depuis n’importe où que je voulais dans le jeu, même dans une fenêtre contextuelle. J'ai décidé d'associer cela à la simplicité et à la convivialité de la liste d'affichage de Flash..

Entrez la classe ScreenHandler.


Étape 3: Votre jeu

Il a probablement de nombreux écrans. Vous avez probablement votre écran d'accueil, menu principal, écran de jeu, crédits, écran de victoire et bien d'autres. Nous devons d'abord installer nos écrans. Nous ne mettrons pas encore de contenu dedans, le gameplay est à vous.

Voici les écrans que j'ai:

Comme vous pouvez le constater, j'ai omis le préchargement. Le préchargement correct est un tout autre tutoriel. Vous pouvez en apprendre plus ici:

Active Tuts +: Le guide complet pour précharger un seul fichier swf

Je vais vous expliquer comment combiner cela avec ce tutoriel vers la fin. Passons maintenant à la partie que vous attendiez tous!


Étape 4: La classe ScreenHandler

La classe ScreenHandler est essentiellement un objet d'affichage qui contient tous vos écrans et les bascule en interne à volonté. Le code est étonnamment simple. Cependant, je ne vais pas simplement vous poser un mur de code. Ce serait un gaspillage si vous ne compreniez pas complètement le code. Je vais donc le décomposer en quelques sections.

La première chose à faire est de créer la classe actuelle. Voici le code:

 package import flash.display.Sprite; Classe publique ScreenHandler étend Sprite // Les variables vont ici Fonction publique ScreenHandler () // Le constructeur va ici // Les fonctions vont ici

Wow, c'est extrêmement vide.

Nous ajouterons ensuite dans nos écrans en tant que variables:

 var privé splashScreen: SplashScreen; private var mainMenu: MainMenu; private var levelSelect: LevelSelect; jeu var privé: jeu; crédits var privés: crédits; Victoire var privée: Victory;

Il suffit de jeter ceux-ci sous le commentaire "Variables go here".

Et juste comme ça, nous sommes à 1 / 10ème du chemin!


Étape 5: Qu'est-ce qui le motive?

C’est la fonction que vous appellerez pour changer d’écran. La bonne nouvelle est qu'il ne s'agit que de 4 lignes de code. La mauvaise nouvelle est que c'est uniquement parce que j'aime décomposer mon code en morceaux gérables. Il s’agit de la seule fonction publique de toute la classe car c’est tout ce dont vous avez besoin pour appeler la classe. L'encapsulation à son meilleur!

 fonction publique switchTo (screenName: String): void newScreenName = screenName; switchScreens (); 

Cela passe sous le commentaire "Fonctions allez ici". Simple, non? Maintenant, vous devez créer une variable appelée newScreenName et une fonction appelée switchScreens..

 private var newScreenName: String = "";

Vous savez déjà où cela va. Et voici la fonction switchScreens:

 fonction privée switchScreens (): void removeOldScreen (); makeNewScreen (); 

Je vous ai prévenu: des morceaux gérables.


Étape 6: Je ne sais toujours rien!!!

Avant de vous mettre en colère contre moi, sachez que je le fais pour votre bien. Pas vraiment. Le diviser en morceaux faciles à gérer facilite la recherche et la modification du code si vous avez besoin de fonctionnalités personnalisées. Moi-même, je trouve toujours le besoin de changer de code plus tard dans le jeu, alors je viens d'adopter cette pratique de codage. De plus, si vous écrivez du code et que quelque chose est cassé, il est plus facile de trouver la source du problème. Ok, assez de mon détournement. Voici les fonctions qui rendent cela possible (pour de vrai cette fois).


Étape 7: La beauté de la liste d'affichage

La fonction removeOldScreen tire sa fonctionnalité miraculeuse de la liste d'affichage d'AS3. C'était probablement la meilleure amélioration par rapport à AS2. La relation parent-enfant de la liste d’affichage est extrêmement utile dans presque toutes les manipulations visuelles. En outre, la lecture en boucle des enfants dans un objet d’affichage est plus rapide que celle effectuée dans un tableau. C'est vraiment génial. Avant d'écrire les fonctions removeOldScreen et makeNewScreen, nous avons besoin d'un parent pour gérer les écrans. Voici une autre variable:

 private var screenLayer: Sprite = new Sprite ();

et ajoutez cette ligne de code à votre constructeur:

 this.addChild (screenLayer);

Très bien, nous avons maintenant une fondation parente qui permet une modification et un débogage faciles. Il ne reste plus qu'à écrire la fonction removeOldScreen. Voici le code:

 fonction privée removeOldScreen (): void var oldScreen: MovieClip; oldScreen = screenLayer.getChildAt (0) en tant que MovieClip; screenLayer.removeChild (oldScreen); 

Nous créons une variable de substitution qui va devenir notre écran actuel. Nous saisissons ensuite l’enfant à l’index de «0» (qui est le premier enfant de l’objet parent) et définissons notre espace réservé sur ce dernier. Cette méthode pratique nous permet de faire ce que nous voulons pour n’importe quel écran sans avoir à appeler le nom de variable spécifique à cet écran. Nous utilisons ensuite la méthode removeChild pour supprimer définitivement l’écran. Juste magnifique.

Eh bien, maintenant nous pouvons faire un écran vide. Ce serait bien de pouvoir y mettre quelque chose, non? Eh bien, je suis sur le point de vous dire comment faire cela.


Étape 8: Correction de l'écran vide

C'est la section la plus détaillée du code, mais il est très facile à créer, à comprendre et à personnaliser. Cette section du code est essentiellement une instruction de commutateur géant contenant tous vos écrans. L'argument que nous transmettons à la fonction switch est la variable newScreenName que nous avons définie dans la fonction switchTo..

 fonction privée makeNewScreen (): void switch (newScreenName) case "SplashScreen": splashScreen = new SplashScreen (); screenLayer.addChild (splashScreen); Pause; case "MainMenu": mainMenu = new MainMenu (); screenLayer.addChild (mainMenu); Pause; case "LevelSelect": levelSelect = new LevelSelect (); screenLayer.addChild (levelSelect); Pause; case "Game": game = new Game (); screenLayer.addChild (jeu); Pause; case "Credits": credits = new Credits (); screenLayer.addChild (crédits); Pause; case "Victory": victoire = nouvelle victoire (); screenLayer.addChild (victoire); Pause; défaut: mainMenu = new MainMenu (); screenLayer.addChild (mainMenu); Pause;  newScreenName = ""; 

Le code est assez explicite, mais je vais l'expliquer quand même..

 case "Screen": screen = new Screen (); screenLayer.addChild (écran); Pause;

Vous associez une chaîne à un écran. Cette chaîne est l'argument que vous allez transmettre à la fonction switchTo. Il parcourt ensuite l'instruction switch et sélectionne l'écran correct à ajouter. Il construit ensuite une instance de la variable et l'ajoute au screenLayer. Vous n'êtes pas obligé de définir une valeur par défaut, mais il est utile de définir une valeur par défaut pour toute instruction switch utilisée à des fins de débogage. Il s'active si aucun des autres cas ne correspond à l'argument.

Remarque: le point d’enregistrement des écrans doit être situé dans le coin supérieur gauche pour que les écrans s’affiche correctement..

Nous avons maintenant les fonctionnalités de la classe ScreenHandler. Il est maintenant temps de l'appliquer à notre programme! Avant de l'appliquer à notre programme, nous devons ajouter un enfant à screenLayer. Sinon, nous n'aurons rien à supprimer lorsque nous appelons removeOldScreen pour la première fois. Cela nous donnera une erreur, et les erreurs sont mauvaises. Mkay?

 splashScreen = new SplashScreen (); screenLayer.addChild (splashScreen);

Ajoutez cela sous le reste du constructeur. Maintenant, allez en haut de la classe et importez flash.display.MovieClip, si vous ne l’avez pas déjà fait, et on peut passer à autre chose..


Étape 9: le faire fonctionner

Si vous n'avez pas consulté le didacticiel auquel j'ai fait référence précédemment, le moment est peut-être venu de le faire..

Active Tuts +: Le guide complet pour précharger un seul fichier swf

Retour? Génial.

Le gestionnaire d'écran sera ajouté à la classe Application. Le sprite lui-même sera une variable statique publique. Vous pourrez donc le référencer à partir de n'importe où dans votre code, ce qui changera d'écran. Facile, droit?

 public var var screen: ScreenHandler = new ScreenHandler ();

puis ajoutez ceci au constructeur de la classe Application:

 this.addChild (écrans);

Si vous avez besoin de changer d'écran de n'importe où dans votre code, procédez comme suit:

 Application.screens.switchTo ("SelectedScreen");

Étape 10: il y a plus?

Eh bien, nous en avons terminé avec le gestionnaire d'écran en soi. Après avoir codé tous les boutons pour passer à l'écran de mon choix, cela fonctionne..

Vous pouvez dire: "Thomas, cette commutation d’écran est moche! Je veux des transitions d’écran!"

C'est une bonne chose que les codes soient facilement personnalisables. Il suffit de demander gentiment la prochaine fois.


Étape 11: Bien paraître

La première étape dans l'ajout de transitions d'écran consiste à déterminer le type de transition d'écran souhaité. Pour cet exemple, je vais simplement faire un fondu d'entrée et de sortie. Facile à droite?

  • Commencez par créer un nouveau symbole.
  • Nommez-le Transition et exportez-le pour actionscript.
  • Dessine un rectangle de la taille de ton écran.
  • Créer une nouvelle image clé sur l'image 10.
  • Créer une nouvelle image clé sur l'image 20.
  • Revenez à la première image et convertissez l'alpha en 0;
  • Passez à l'image 20 et convertissez l'alpha en 0;
  • Faites un clic droit sur l'espace entre les images clés et sélectionnez 'Créer une interpolation de forme'.

Votre transition d'écran terminée devrait ressembler à ceci:

Maintenant que nous avons cette configuration, codons notre classe de transition!


Étape 12: Une petite classe

Il s'agit d'une classe simple à configurer pour nos besoins, même si vous pouvez toujours la personnaliser pour répondre à vos besoins. Il doit étendre MovieClip, et la seule chose que nous y ajoutons est une variable..

 package import flash.display.MovieClip; import flash.events.Event; Classe publique Transition étend MovieClip public static var exitFrames: Number = 11; var timer privé: Nombre = 0; fonction publique ScreenTransition () this.addEventListener (Event.ENTER_FRAME, remove); this.addEventListener (Event.REMOVED_FROM_STAGE, removeListeners);  fonction privée remove (e: Event): void timer ++; if (timer> = 20) parent.removeChild (this);  fonction privée removeListeners (e: Event): void this.removeEventListener (Event.ENTER_FRAME, remove); this.removeEventListener (Event.REMOVED_FROM_STAGE, removeListeners); 

La variable que nous avons ajoutée était exitFrames. Nous l'avons mis à 11. Pourquoi? Parce que c’est le cadre dans lequel la transition atteint 100% alpha et c’est le cadre sur lequel nous allons activer les écrans. Les autres fonctions traitent de la suppression du clip lui-même et de la suppression des écouteurs d'événements une fois qu'il a été supprimé. Moins de collecte des ordures, hein?


Étape 13: Mais vous ne dites aucun événement!

Rappelez-vous comment j'ai dit que nous n'utiliserions pas les événements? Eh bien, j'ai menti. La transition d'écran nécessite quelques événements pour que la commutation de l'écran retarde correctement et que la transition soit supprimée une fois son travail terminé..

Depuis le début, mon objectif était de rendre cette classe aussi polyvalente et facile à utiliser que possible. Je ne voulais pas avoir mal à la tête lorsque j'ai configuré l'architecture de mon écran. En suivant ces directives, je ferai de l'ajout de transitions d'écran une option, car parfois, une transition d'écran n'est pas nécessaire..


Étape 14: Changer les choses

Pour ajouter des transitions d'écran, nous n'avons même pas besoin de toucher le code removeOldScreen ou makeNewScreen car je les ai séparés au préalable. C'est presque comme si je savais que cela allait arriver…

Nous allons avoir besoin d'une multitude de nouvelles variables:

 private var transitionLayer: Sprite = new Sprite (); transition var privée: Transition; private var transTimer: Number = 0; var privé makeTransition: Boolean;

La transitionLayer va héberger notre clip de transition. Ainsi, cela n’interférera pas avec le nombre d’enfants de notre screenLayer. Le temporisateur de transition sera utilisé pour chronométrer nos actions dans l'événement juste comme il faut. La variable make transition va contrôler si une transition d'écran sera utilisée, c'est vous qui décidez!

Ensuite, nous devrons également changer les choses dans le constructeur. Voici à quoi devrait ressembler votre nouveau constructeur:

 this.addChild (screenLayer); this.addChild (transitionLayer); splashScreen = new SplashScreen (); screenLayer.addChild (splashScreen);

Enfin, allez dans la zone d'importation et importez flash.events.Event. Après cela nous pouvons faire place.


Étape 15: Réutilisation de la fonction switchTo

Je veux toujours garder cette fonction courte et douce, afin de ne pas compliquer le résultat final de l'utilisateur. L'encapsulation est géniale, non?

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

Il y a beaucoup de nouvelles choses ici. Dans la section arguments, nous avons ajouté trans, qui est défini sur true par défaut. Cela signifie que, sauf indication contraire de votre part, il est automatiquement configuré pour effectuer une transition d'écran. Cela vous évite d'avoir à taper 'vrai' chaque fois que vous changez d'écran. Notre variable makeTransition est alors définie égale à trans. La fonction switchScreens acceptera maintenant un argument d'événement, ce qui nous amène à la section suivante.


Étape 16: Travailler à nouveau avec la fonction switchScreens

Concentrons-nous sur le code pour que la transition d'écran fonctionne en premier. Ceci comportera une bonne quantité de changement de notre code précédemment simple.

 fonction privée 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); 

Permettez-moi de le décomposer:

 fonction privée switchScreens (e: Event): void transTimer ++; if (transTimer == 1 && transitionLayer.numChildren < 1) transition = new Transition(); transitionLayer.addChild(transition); 

Nous ajoutons d'abord un argument Event dans la fonction. Nous paramétrons le transTimer pour qu’il augmente d’une unité toutes les images. Si le transTimer est égal à un et que la transitionLayer n'a pas d'enfants, nous ajoutons une transition.

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

Une fois que le transTimer a atteint les exitFrames définis précédemment, nous effectuons le changement d’écran. Parce que c'est ce dont il s'agit, non? Ensuite, il réinitialise le transTimer, puis supprime l'écouteur d'événements. Maintenant, il change d'écran avec une transition en douceur!


Étape 17: Réutilisation de la fonction switchScreen (2e partie)

Nous allons maintenant accepter la possibilité que vous ne souhaitiez pas qu'une transition d'écran se produise. Nous allons envelopper tout notre code switchScreens actuel dans une instruction if:

 if (makeTransition) // Tout votre code switchScreens actuel va ici

N'était-ce pas facile? Nous créons maintenant une section else pour quand makeTransition n’est pas vrai:

 if (makeTransition) // Tout votre code switchScreens actuel va ici else removeOldScreen (); makeNewScreen (); this.removeEventListener (Event.ENTER_FRAME, switchScreens); 

Et voilà, une classe de gestion d’écran entièrement fonctionnelle avec la capacité de contrôler l’ajout de transitions d’écran! Super truc.


Étape 18: La classe Full ScreenHandler

Voici à quoi ressemblera le code fini:

 package import flash.display.Sprite; import flash.display.MovieClip; import flash.events.Event; Classe publique ScreenHandler étend Sprite private var splashScreen: SplashScreen; private var mainMenu: MainMenu; private var levelSelect: LevelSelect; jeu var privé: jeu; crédits var privés: crédits; Victoire var privée: Victory; private var newScreenName: String = ""; private var screenLayer: Sprite = new Sprite (); private var transitionLayer: Sprite = new Sprite (); transition var privée: Transition; private var transTimer: Number = 0; var privé makeTransition: Boolean; fonction publique ScreenHandler () this.addChild (screenLayer); this.addChild (transitionLayer); splashScreen = new SplashScreen (); screenLayer.addChild (splashScreen);  fonction publique switchTo (screenName: String, trans: Boolean = true): void newScreenName = screenName; makeTransition = trans; this.addEventListener (Event.ENTER_FRAME, switchScreens);  fonction privée 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 = "";   

Voici comment vous l'implémentez dans la classe Application:

 public var var screen: ScreenHandler = new ScreenHandler ();

dans le constructeur Applications, ajoutez

 this.addChild (écrans);

et utilisez cette fonction de n’importe où dans votre code pour changer d’écran:

 Application.screens.switchTo ("SelectedScreen");

Si vous ne voulez pas de transition d'écran:

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

Étape 19: Le produit fini


Étape 20: Profitez

Je crois avoir accompli ce que je voulais faire. La classe est facile à utiliser et encore plus polyvalente dans l’ajout de transitions d’écran que la bonne chronologie. J'espère que vous tirerez parti de cette classe et que vous pourrez même l'améliorer et la rendre encore plus polyvalente. Le ciel est la limite avec les transitions d'écran, et peut-être (probablement), vous pouvez trouver de meilleures méthodes de gestion de l'architecture d'écran: la méthode la plus simple.!


Conclusion

J'espère que vous avez aimé ce tutoriel, merci d'avoir lu!