Manejo de la arquitectura de pantalla la manera sin dolor!

¿Alguna vez pensó que la arquitectura de la pantalla era una tarea innecesariamente dolorosa y tediosa? Entonces este tutorial es tu amigo..

Encontramos a este increíble autor gracias a FlashGameLicense.com, el lugar para comprar y vender juegos Flash.!


Vista previa del resultado final

Echemos un vistazo al resultado final en el que trabajaremos:


Paso 1: El proceso de selección

Si eres como yo, siempre odié el inicio de un proyecto, porque tendría que configurar todas las pantallas. Después de que dejé de codificar en la línea de tiempo, perdí la facilidad de solo decir: gotoAndStop (x).

Como todos sabemos, la codificación de la línea de tiempo es simplemente incorrecta; Contamina el medio ambiente y provoca caries. Sin embargo, era sencillo cambiar las pantallas. Pasé mucho tiempo en línea tratando de encontrar un método eficiente de cambio de pantalla, pero todo lo que encontré fueron métodos llenos de dolor, castigando al desarrollador por tener arquitecturas de pantalla complejas. Y el hecho de no cambiar las pantallas de la pantalla base me hizo pegar un código feo en mi juego, como por ejemplo:

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

¿Ves lo que quiero decir? Evento personalizado tras evento personalizado, me cansé de este absurdo. Tiene que haber una mejor manera.


Paso 2: La luz al final del túnel

Por lo tanto, me propuse encontrar un método para manejar arquitecturas de pantalla complejas sin todo ese trauma mental molesto. No hay eventos. Pasé a mi forma favorita de manejar las tareas que necesitan referenciarse desde cualquier parte del juego: variables estáticas y métodos.

El uso de variables estáticas me permitiría hacer referencia a un objeto desde cualquier lugar que quisiera en el juego, incluso en una ventana emergente de una ventana emergente emergente. Decidí unir esto con la simplicidad y la facilidad de uso de la lista de visualización de Flash.

Ingrese a la clase ScreenHandler.


Paso 3: tu juego

Probablemente tiene muchas pantallas. Es probable que tengas tu pantalla de bienvenida, menú principal, pantalla de juego, créditos, pantalla de victoria y muchos otros. Necesitamos configurar nuestras pantallas primero. No pondremos ningún contenido en él todavía, el juego depende de ti..

Aquí están las pantallas que tengo:

Como puedes ver, he dejado fuera el precargador. Precargar correctamente es otro tutorial completo. Puedes aprender sobre esto aquí:

Active Tuts +: la guía completa para precargar un solo archivo swf

Te explicaré cómo combinar esto con ese tutorial cerca del final. Ahora a la parte que todos han estado esperando!


Paso 4: La clase ScreenHandler

Esencialmente, la clase ScreenHandler es un objeto de visualización que contiene todas sus pantallas y las cambia internamente a voluntad. El código es sorprendentemente simple. Sin embargo, no solo colocaré una pared de código para que la encuentres. Sería un desperdicio si no entendiera completamente el código. Así que lo dividiré en un par de secciones..

Lo primero que debemos hacer es crear la clase real. Aquí está el código:

 paquete import flash.display.Sprite; clase pública ScreenHandler extiende Sprite // Variables ir aquí función pública ScreenHandler () // El constructor va aquí // Funciones ir aquí

Wow, eso es extremadamente vacío.

A continuación añadiremos en nuestras pantallas como variables:

 privado var splashScreen: SplashScreen; privado var mainMenu: MainMenu; privado var levelSelect: LevelSelect; juego de var privado: juego; Créditos var privados: Créditos; victoria de var privado: Victoria;

Solo tira esos bajo el comentario "Las variables van aquí".

Y así, estamos a la décima parte del camino.!


Paso 5: Lo que hace que funcione

Esta es la función a la que llamarás para cambiar tus pantallas. La buena noticia es que solo son 4 líneas de código. La mala noticia es que es solo porque me gusta descomponer mi código en partes manejables. Esta es la única función pública en toda la clase, ya que esto es todo lo que necesita llamar para que la clase funcione. Encapsulación en su máxima expresión!

 función pública switchTo (screenName: String): void newScreenName = screenName; switchScreens (); 

Eso va bajo el comentario "Las funciones van aquí". Simple, no? Ahora necesita crear una variable llamada newScreenName y una función llamada switchScreens.

 private var newScreenName: String = "";

Ya sabes a dónde va eso. Y aquí está la función switchScreens:

 Función privada switchScreens (): void removeOldScreen (); makeNewScreen (); 

Te lo advertí: trozos manejables.


Paso 6: Todavía no sé nada!!!

Antes de que te enojes conmigo, date cuenta de que estoy haciendo esto por tu propio bien. No realmente. Dividirlo en partes manejables como esta le facilita encontrar y modificar el código si necesita una funcionalidad personalizada. Yo mismo siempre encuentro la necesidad de cambiar el código más adelante en el juego, así que simplemente adopté esta práctica de codificación. Además, si está escribiendo código y algo está roto, es más fácil encontrar la fuente del problema. Ok, basta de mi desvío. Aquí están las funciones que lo hacen realidad (de verdad esta vez).


Paso 7: La belleza de la lista de visualización

La función removeOldScreen toma su funcionalidad milagrosa de la lista de visualización de AS3. Esta fue probablemente la mejor mejora de AS2. La relación padre-hijo que tiene la lista de visualización es extremadamente útil en casi cualquier manipulación visual, y recorrer los hijos en un objeto de visualización es más rápido que pasar por MovieClips en una matriz. Realmente es genial. Antes de escribir las funciones removeOldScreen y makeNewScreen, necesitamos un padre para mantener las pantallas. Aquí hay otra variable:

 private var screenLayer: Sprite = new Sprite ();

y agregue esta línea de código a su constructor:

 this.addChild (screenLayer);

Bien, ahora tenemos una base principal que permite una fácil modificación y depuración. Todo lo que queda por hacer es escribir la función removeOldScreen. Aquí está el código:

 función privada removeOldScreen (): void var oldScreen: MovieClip; oldScreen = screenLayer.getChildAt (0) como MovieClip; screenLayer.removeChild (oldScreen); 

Lo que estamos haciendo es crear una variable de marcador de posición que se va a "convertir" en nuestra pantalla actual. Luego tomamos el elemento secundario en el índice de '0' (que es el primer elemento secundario del objeto principal) y le asignamos un marcador de posición igual. Este método conveniente nos permite hacer lo que queramos en cualquier pantalla sin tener que llamar el nombre de variable específica de la pantalla. Luego usamos el método removeChild para deshacernos de la pantalla para siempre. Simplemente hermoso.

Bueno, ahora podemos hacer una pantalla en blanco. Sería bueno poder poner algo ahí, ¿verdad? Bueno, estoy a punto de decirte cómo hacerlo..


Paso 8: Rectificar la pantalla en blanco

Esta es la sección más detallada del código, pero es muy fácil de hacer, entender y personalizar. Esta sección del código es básicamente una declaración de cambio gigante que contiene todas sus pantallas. El argumento que pasamos a la función de cambio es la variable newScreenName que establecimos en la función de cambio..

 función privada makeNewScreen (): void switch (newScreenName) caso "SplashScreen": splashScreen = new SplashScreen (); screenLayer.addChild (splashScreen); descanso; caso "MainMenu": mainMenu = new MainMenu (); screenLayer.addChild (mainMenu); descanso; caso "LevelSelect": levelSelect = new LevelSelect (); screenLayer.addChild (levelSelect); descanso; caso "Juego": juego = juego nuevo (); screenLayer.addChild (juego); descanso; caso "Créditos": créditos = créditos nuevos (); screenLayer.addChild (créditos); descanso; caso "Victoria": victoria = nueva Victoria (); screenLayer.addChild (victoria); descanso; por defecto: mainMenu = new MainMenu (); screenLayer.addChild (mainMenu); descanso;  newScreenName = ""; 

El código es bastante autoexplicativo, pero lo explicaré de todos modos.

 caso "Pantalla": pantalla = pantalla nueva (); screenLayer.addChild (pantalla); descanso;

Asocia una cadena a una pantalla. Esa cadena es el argumento que pasará a la función switchTo. Luego pasa a través de la instrucción de cambio y selecciona la pantalla correcta para agregar. Luego construye una instancia de la variable y la agrega al screenLayer. No es necesario que establezca un valor predeterminado, pero es útil tener un valor predeterminado para cualquier instrucción de cambio que tenga para fines de depuración. Se activa si ninguno de los otros casos coincide con el argumento..

Nota: el punto de registro de las pantallas debe estar en la esquina superior izquierda para que las pantallas se muestren correctamente.

Ahora tenemos la funcionalidad detrás de la clase ScreenHandler. ¡Ahora es el momento de aplicarlo a nuestro programa! Antes de aplicarlo a nuestro programa, debemos agregar un hijo al screenLayer; de lo contrario, no tendremos nada que eliminar cuando llamemos removeOldScreen la primera vez. Esto nos dará un error, y los errores son malos. Mkay?

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

Agregue eso debajo del resto del constructor. Ahora ve a la parte superior de la clase e importa flash.display.MovieClip, si aún no lo has hecho, y podemos continuar..


Paso 9: Hacer que funcione

Si no has mirado el tutorial al que hice referencia anteriormente, ahora podría ser el momento de hacerlo..

Active Tuts +: la guía completa para precargar un solo archivo swf

¿Espalda? Genial.

El controlador de pantalla se agregará a la clase de aplicación. El sprite real en sí mismo será una variable estática pública, por lo que puede hacer referencia a ella desde cualquier lugar en su código y cambiará la pantalla. Fácil a la derecha?

 Pantallas de var estáticas públicas: ScreenHandler = new ScreenHandler ();

luego agregue esto al constructor de la clase de aplicación:

 this.addChild (pantallas);

Si alguna vez necesitas cambiar las pantallas desde cualquier lugar en tu código, así es como lo haces:

 Application.screens.switchTo ("SelectedScreen");

Paso 10: Hay más?

Bueno, hemos terminado con el controlador de pantalla per se. Después de codificar todos los botones para cambiar a cualquier pantalla que desee, funciona.

Puedes decir: "¡Thomas, este cambio de pantalla es feo! ¡Quiero transiciones de pantalla!"

Bueno, es bueno que los códigos sean fácilmente personalizables. Solo pregunta amablemente la próxima vez.


Paso 11: hacer que se vea bien

El primer paso para agregar transiciones de pantalla es decidir qué tipo de transición de pantalla desea. Para este ejemplo, solo voy a hacer una salida y desaparición simples.?

  • Comience por hacer un nuevo símbolo.
  • Asígnele el nombre Transición y expórtelo para ActionScript..
  • Dibuja un rectángulo del tamaño de tu pantalla..
  • Hacer un nuevo fotograma clave en el marco 10.
  • Hacer un nuevo fotograma clave en el marco 20.
  • Vuelve al cuadro uno y convierte el alfa a 0;
  • Ve al cuadro 20 y convierte el alfa a 0;
  • Haga clic derecho en el espacio entre los fotogramas clave y seleccione "Crear interpolación de forma".

Su transición de pantalla terminada debería verse así:

Ahora que tenemos esa configuración, codifiquemos nuestra clase de Transición!


Paso 12: Un poco de clase

Esta es una clase simple para configurar para nuestros propósitos, aunque siempre puede personalizarla para solucionar sus necesidades. Necesita extender MovieClip, y lo único que le estamos agregando es una variable.

 paquete import flash.display.MovieClip; import flash.events.Event; Transición de clase pública extiende MovieClip public static var exitFrames: Number = 11; temporizador var privado: Número = 0; función pública ScreenTransition () this.addEventListener (Event.ENTER_FRAME, eliminar); this.addEventListener (Event.REMOVED_FROM_STAGE, removeListeners);  función privada remove (e: Event): void timer ++; if (timer> = 20) parent.removeChild (this);  función privada removeListeners (e: Event): void this.removeEventListener (Event.ENTER_FRAME, remove); this.removeEventListener (Event.REMOVED_FROM_STAGE, removeListeners); 

La variable que agregamos fue exitFrames. Lo configuramos a 11. ¿Por qué? Porque ese es el marco en el que la transición alcanza el 100% alfa, y es el marco en el que vamos a encender las pantallas. Las otras funciones controlan la eliminación del clip en sí y la eliminación de escuchas de eventos una vez que se ha eliminado. Menos recolección de basura, eh?


Paso 13: Pero no dijiste eventos!

¿Recuerdas que dije que no usaríamos eventos? Bueno, mentí. La transición de la pantalla requiere algunos eventos para que el cambio de pantalla se retrase correctamente y la transición se elimine una vez que haya finalizado su trabajo..

Desde el principio, mi objetivo era hacer que esta clase fuera lo más versátil y fácil de usar posible. No quise ningún dolor de cabeza cuando configuré mi arquitectura de pantalla. De acuerdo con esas pautas, haré que agregar transiciones de pantalla sea una opción, ya que a veces, una transición de pantalla no es necesaria.


Paso 14: Cambiando las cosas alrededor

Para agregar transiciones de pantalla, ni siquiera tenemos que tocar el código removeOldScreen o makeNewScreen porque los separé de antemano. Es casi como si supiera que esto iba a suceder ...

Vamos a necesitar un montón de nuevas variables:

 privado var transitionLayer: Sprite = new Sprite (); transición var privada: Transición; variable var transTimer: Número = 0; var privado Transición: booleano;

La transiciónLayer va a alojar nuestro clip de transición. De esa manera no interfiere con el número de hijos de nuestro ScreenLayer. El temporizador de transición se utilizará para sincronizar nuestras acciones en el evento justo a la derecha. La variable de transición de transición controlará si se usará una transición de pantalla, eso depende de usted!

A continuación, vamos a necesitar cambiar las cosas en el constructor también. Este es el aspecto que debería tener tu nuevo constructor:

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

Y por último, pero no menos importante, vaya a su área de importación e importe flash.events.Event. Después de eso podemos dar paso..


Paso 15: Re-trabajando la función switchTo

Todavía quiero mantener esta función breve y dulce, para no complicar el resultado final del usuario. La encapsulación es genial, no?

 función pública switchTo (screenName: String, trans: Boolean = true): void newScreenName = screenName; makeTransition = trans; this.addEventListener (Event.ENTER_FRAME, switchScreens); 

Hay muchas cosas nuevas aquí. En la sección de argumentos, agregamos trans, que se establece en verdadero de forma predeterminada. Esto significa que, a menos que usted diga lo contrario, se configura automáticamente para hacer una transición de pantalla. Esto le ahorra la molestia de tener que escribir 'verdadero' cada vez que cambia de pantalla. Nuestra variable makeTransition se establece igual a trans. La función switchScreens ahora aceptará un argumento de evento, lo que nos lleva a la siguiente sección.


Paso 16: Re-trabajando la función switchScreens

Centrémonos en el código para que la transición de pantalla funcione primero. Esto contará con una buena cantidad de cambio de nuestro código previamente simple.

 Función privada 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); 

Déjame descomponerlo:

 Función privada switchScreens (e: Event): void transTimer ++; if (transTimer == 1 && transitionLayer.numChildren < 1) transition = new Transition(); transitionLayer.addChild(transition); 

Primero agregamos un argumento de evento a la función. Configuramos el transTimer para aumentar en uno cada cuadro. Si el transTimer es igual a uno, y la transiciónLayer no tiene hijos, agregamos una transición.

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

Una vez que el transTimer alcanza los marcos de salida que establecimos anteriormente, hacemos que el cambio de pantalla ocurra. Porque de eso se trata, ¿verdad? Luego restablece el transTimer, luego elimina el detector de eventos. Ahora cambia las pantallas con una transición de pantalla suave!


Paso 17: Re-trabajando la función switchScreen (Parte 2)

Ahora nos adaptaremos a la posibilidad de que no desee que se produzca una transición de pantalla. Vamos a envolver todo nuestro código actual de SwitchScreens en una sentencia if:

 if (makeTransition) // Todo el código actual de su SwitchScreens va aquí

¿No fue eso fácil? Ahora hacemos otra sección para cuando makeTransition no es cierto:

 if (makeTransition) // Todo su código actual de switchScreens va aquí else removeOldScreen (); makeNewScreen (); this.removeEventListener (Event.ENTER_FRAME, switchScreens); 

Y ahí lo tienen, ¡una clase de manejo de pantalla completamente funcional con la capacidad de controlar la adición de transiciones de pantalla! Buena cosa.


Paso 18: La clase completa de ScreenHandler

Así es como se verá el código terminado:

 paquete import flash.display.Sprite; importar flash.display.MovieClip; import flash.events.Event; la clase pública ScreenHandler extiende Sprite private var splashScreen: SplashScreen; privado var mainMenu: MainMenu; privado var levelSelect: LevelSelect; juego de var privado: juego; Créditos var privados: Créditos; victoria de var privado: Victoria; private var newScreenName: String = ""; private var screenLayer: Sprite = new Sprite (); privado var transitionLayer: Sprite = new Sprite (); transición var privada: Transición; variable var transTimer: Número = 0; var privado Transición: booleano; función pública ScreenHandler () this.addChild (screenLayer); this.addChild (transitionLayer); splashScreen = nuevo SplashScreen (); screenLayer.addChild (splashScreen);  función pública switchTo (screenName: String, trans: Boolean = true): void newScreenName = screenName; makeTransition = trans; this.addEventListener (Event.ENTER_FRAME, switchScreens);  función privada 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 = "";   

Así es como lo implementas en la clase Aplicación:

 Pantallas de var estáticas públicas: ScreenHandler = new ScreenHandler ();

en el constructor Aplicaciones, agregue

 this.addChild (pantallas);

y use esta función desde cualquier lugar en su código para cambiar de pantalla:

 Application.screens.switchTo ("SelectedScreen");

Si no quieres una transición de pantalla:

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

Paso 19: El producto terminado


Paso 20: disfrutar

Creo que logré lo que me propuse hacer. La clase es fácil de usar y aún más versátil en agregar transiciones de pantalla que la línea de tiempo de la buena ole. Espero que aproveches esta clase e incluso la mejores y la vuelvas aún más versátil. El cielo es el límite con las transiciones de pantalla, y tal vez (probablemente), puede encontrar métodos mejorados para manejar la arquitectura de la pantalla: la forma indolora!


Conclusión

Espero que te haya gustado este tutorial, gracias por leerlo.!