En este tutorial, crearemos un sistema de texto similar a lo que ves en muchos juegos de rol. Nuestra clase mostrará dinámicamente un icono para los caracteres mientras hablan, y escribirá cada bloque de texto letra por letra.
Aquí hay un ejemplo del sistema de texto que crearemos:
Crear un nuevo archivo Flash (Actionscript 3). La configuración de tu película variará dependiendo de tu juego. Para esta demostración, estoy configurando mi película como 500x300, con un fondo negro y 30 fps.
Lo más probable es que esté mostrando el módulo de texto sobre una imagen o animación de su juego. Para esta demostración, solo estoy usando una imagen que lancé junto con algunos de los personajes de mis juegos de pie en un campo de nieve..
Pon tu imagen de fondo en una capa llamada "fondo".
Cree un nuevo MovieClip en el escenario (Insertar> MovieClip) llamado "RPGText".
En las Propiedades del símbolo, marque "Exportar para Actionscript" y configure el nombre de la clase en "RPGText". Usaremos este nombre de clase más adelante para vincular el código a este MovieClip.
Haga clic en Aceptar. Si ve una advertencia aquí de que no se pudo encontrar la definición de la clase, está bien. Simplemente significa que no hay ningún código para vincular a este símbolo (todavía).
Dale a tu MovieClip el nombre de instancia "rpgText". Recuerde, cuando estoy hablando de "RPGText" (en mayúsculas) me refiero a la clase (o MovieClip); "rpgText" (en minúsculas) es el nombre de un ejemplo de esa clase.
Dibuja un rectángulo dentro de tu nuevo RPGTexto MovieClip. Este será el fondo para los iconos de caracteres y bocadillos. Diseña como quieras, pero debe abarcar todo el ancho de tu película y ser lo suficientemente corto como para que no cubra demasiado tu juego..
Hice el mío 500px de ancho (para que coincida con mi película) y 100px de altura. Lo llené con un gradiente de # 666666 a # 999999 (gris oscuro a gris más claro).
Consejo rapido: Para dibujar un rectángulo de un tamaño específico, seleccione la herramienta Rectángulo y presione la tecla Alt y haga clic en el escenario. Obtendrá un cuadro de diálogo donde puede ingresar las dimensiones de su rectángulo.
Crear una nueva capa dentro de la RPGTexto MovieClip llamado "icono". Cree un nuevo clip de película en esta capa llamada "characterIcon" y asígnele el nombre de instancia "characterIcon".
Dentro de carácterIcono MovieClip crea dos nuevas capas: "iconos" y "etiquetas". La capa de iconos contendrá todos los iconos de tu personaje (cada uno en su propio fotograma clave) y la capa de etiquetas contendrá etiquetas de marco que usaremos para mostrar los personajes en el momento adecuado.
Importe (o dibuje en Flash) un icono para cada uno de los personajes de su juego que hablarán. Para esta demostración hice un JPG de 75x75 px para cada uno de mis personajes. Agrega los iconos a la iconos capa, haciendo un nuevo fotograma clave para cada personaje. El orden en el que aparecen no es importante, pero asegúrese de que cada ícono esté colocado en x: 0, y: 0 para que no parezcan saltar cuando se cambian los caracteres..
Ahora crea un nuevo fotograma clave en cada marco de tu etiquetas capa. Una forma rápida de hacer esto es seleccionar todos los cuadros y presionar F6..
Seleccione cada fotograma clave de la etiqueta uno por uno y agregue una etiqueta de fotograma que corresponda al nombre del carácter que aparece en ese fotograma. Si agrega algunos marcos vacíos (F5) entre los fotogramas clave, facilitará la lectura de las etiquetas de marco, solo asegúrese de que etiquetas fotogramas clave se mantienen alineados con su iconos fotogramas clave.
Asegúrese de que cada una de sus etiquetas tenga un nombre único. Si tiene dos caracteres con el mismo nombre, tendrá que diferenciarlos de alguna manera ('John_L' y 'John_K' por ejemplo).
Volver a la RPGTexto MovieClip y crea una nueva capa llamada "textBackground".
Dibuja un bocadillo. Dibujé una burbuja simple con esquinas cuadradas, pero puedes hacer que el tuyo se vea como quieras. Haz que sea lo suficientemente grande como para que ocupe la mayor parte del rectángulo de fondo y se sienta bien junto a los iconos de tu personaje.
Seleccione su bocadillo y conviértalo a MovieClip (Modificar> Convertir a símbolo). Ahora que es un MovieClip, podemos agregarle un filtro de sombra. Puse el mío en negro, 50% de fuerza, 5px desenfoque y 1px de distancia.
Crea una nueva capa en el RPGTexto MovieClip llamado "texto". Usa la herramienta de texto para dibujar un cuadro de texto. Haz que encaje justo dentro de los bordes del gráfico de bocadillo.
Conviértalo en un campo de texto dinámico multilínea con el nombre de instancia "txt". Recuerde incrustar la fuente si no está utilizando texto del sistema. Estoy usando 13pt Courier.
Necesitamos una manera para que el jugador avance al siguiente bloque de texto cuando el jugador haya terminado de leer. Añadamos un pequeño botón "siguiente" en la esquina..
Crea una nueva capa en el RPGTexto MovieClip llamado "botón". Agrega un nuevo símbolo de botón llamado "b_next". Diseña los cuatro estados de tu botón como quieras. Usé una pequeña flecha hacia abajo como símbolo de botón porque veo que en muchos juegos asumo que los jugadores están familiarizados con él.
Coloque el botón en la esquina inferior derecha en la parte superior de su burbuja de diálogo. No te preocupes por darle un nombre de instancia. Te explico porque luego.
Cree un nuevo archivo de Actionscript llamado "Main.as" y agregue este código para crear el shell vacío para la clase:
paquete import flash.display.MovieClip; La clase pública Main extiende MovieClip // CONSTRUCTOR public function Main ()
Establezca Main como la Clase de documento en su archivo Flash. Si desea un rápido repaso sobre el uso de una clase de documentos, este consejo rápido de Michael Williams es una de las mejores explicaciones que he visto..
Si está usando esto en un juego, probablemente decida ponerlo en otro lugar, pero por ahora lo agregaremos a la Clase de documentos. Agregue este código a la función constructora en el Principal clase:
var textBlocks: Array = new Array (["Kid", "Look, a robot!"], ["Abe", "BLEEP-BLOOP. Soy un ingeniero botánico autónomo. Puedes llamarme ABE."], [" Niño "," Hola Abe. Conoce a Frosty the Snowman "], [" Frosty "," ¡Feliz cumpleaños! "], [" Abe "," BEEP-BIP. Hola, Frosty. "], [" Abe "," ¿Esta rana te pertenece? "], [" Rana "," Ribbit ... "], [" Niño "," No, nunca lo había visto antes. ¿No eres una rana fría? "], [" Rana " , "Ribbit ...")); rpgText.textBlocks = textBlocks;
Aquí estamos creando una matriz bidimensional (una matriz que contiene otras matrices) para mantener el script para nuestra escena. Antes de cambiar algo, eche un vistazo a cómo está estructurado. Cada matriz es un bloque de texto separado que contiene dos elementos. El primero es el nombre del personaje y el segundo es el texto que hablará. Los bloques de texto se enumeran en el orden en que aparecerán en la escena..
La última línea simplemente envía el bloqueos de texto matriz a la rpgText MovieClip (recuerde que "rpgText" es el nombre de instancia del RPGText MovieClip en el escenario). Más sobre esto más adelante.
Continúa y edita esta sección para que se ajuste a tu escena. Tenga mucho cuidado de que los nombres de los caracteres se correspondan exactamente con los nombres que utilizó para las etiquetas de fotograma en el clip de carácter de carácter.
Finalmente estamos listos para comenzar a escribir el código para la clase RPGText.
Cree un nuevo archivo de Actionscript llamado "RPGText.as" y agregue este código:
package import flash.events.Event; import flash.events.MouseEvent; importar flash.display.MovieClip; import flash.media.Sound; la clase pública RPGText amplía MovieClip private const SPEAKER: int = 0; const privado TEXTO: int = 1; private var _currentTextBlockIndex: int = 0; private var _currentTextBlock: String; private var _textBlocks: Array; // CONSTRUCTOR public function RPGText ()
Esto es solo un shell básico para la clase. Todavía no hace nada, pero echemos un vistazo a lo que hay:
(Nota: estoy usando el guión bajo en los nombres de mis variables para indicar variables privadas).
Desde nuestra _textBlocks La variable es privada. Necesitaremos una forma de acceder a esa variable desde el Principal Clase donde estamos configurando los bloques de texto. Lo haremos creando una función "setter". Agregue esto a la clase RPGText justo debajo de la función constructora:
conjunto de funciones públicas textBlocks (txt: Array): void _textBlocks = txt;
Lo bueno de los configuradores en Flash es que podemos acceder a esta función como si fuera una propiedad pública de la clase RPGText. Que es exactamente lo que hicimos en la línea 21 de la clase principal en el Paso 11:
rpgText.textBlocks = textBlocks;
Agregue esta función a la clase RPGText:
función privada updateText (e: Event): void if (txt.text.length < _currentTextBlock.length) txt.text = _currentTextBlock.substr(0, txt.text.length+1); else removeEventListener(Event.ENTER_FRAME, updateText); fillText();
Esta es la funcionalidad principal de la clase, donde tiene lugar la escritura letra por letra. Echemos un vistazo más de cerca a lo que está pasando aquí:
Agregue esta función a la clase RPGText:
función privada fillText (e: MouseEvent = null): void txt.text = _currentTextBlock; if (_currentTextBlockIndex < _textBlocks.length-1) addEventListener(MouseEvent.CLICK, nextTextBlock);
El propósito principal de esta función es llenar el TXT campo de texto con el texto de la _currentTextBlock (línea 37). Si dejamos pasar la animación, la updateText la función debería encargarse de eso, pero es bueno asegurarse de que nada salga mal. También podemos conectar esta función a nuestro botón "siguiente" para permitir a los jugadores omitir la animación de texto y rellenar inmediatamente el campo de texto con todo el bloque de texto..
Tenga en cuenta que esta función acepta un MouseEvent como argumento, pero establecemos su valor predeterminado en nulo. Esto nos permite utilizar esta función con un oyente MouseEvent, ya que aceptará el evento. Como le damos al evento un valor predeterminado, también podemos llamar a la función sin enviar un evento como lo hacemos al final de la updateText función.
Luego de completar el campo de texto, verificamos si este es el último bloque de texto en la matriz (si el _currentBlockIndex es menor que el número de elementos en el _bloque de texto formación). Si no, agregamos un oyente CLICK para activar una función llamada nextTextBlock que escribiremos a continuación.
¿Recuerdas cuando creamos el botón "siguiente" y dije que no te preocupes por darle un nombre de instancia? ¿Notó en el último paso cómo adjuntamos el oyente CLICK a todo el clip de película RPGText en lugar del botón? Esto hace que el jugador pueda hacer clic en cualquier parte del clip de película para avanzar el texto. Realmente ni siquiera necesitamos el botón, pero me gusta poner uno, así que hay algunas indicaciones de que hace clic para avanzar el texto..
Por supuesto, esto es solo una preferencia personal mía. Si lo desea, puede darle al botón un nombre de instancia y adjuntar el oyente CLICK al botón en su lugar. Simplemente encuentro que el área de impacto más grande es más fácil de usar.
De vuelta a los negocios. Agregue esta función a la clase RPGText:
función privada nextTextBlock (e: MouseEvent): void removeEventListener (MouseEvent.CLICK, nextTextBlock); txt.text = ""; // borrar el texto _currentTextBlockIndex ++; _currentTextBlock = _textBlocks [_currentTextBlockIndex] [TEXT]; // establece el carácter de textoIcon.gotoAndStop (_textBlocks [_currentTextBlockIndex] [SPEAKER]); // establece el icono de carácter addEventListener (Event.ENTER_FRAME, updateText); // comenzar a actualizar el texto addEventListener (MouseEvent.CLICK, fillText);
Las tres primeras líneas son bastante simples. Elimine el agente de escucha MouseEvent, borre el campo de texto e incremente el _currentTextBlockIndex var para apuntar al siguiente bloque de texto.
La línea 47 está usando el TEXTO constante para obtener la cadena de texto actual de la _textBlocks Array y asignarlo a _currentTextBlock.
A continuación usamos el ALTAVOZ Constante para obtener el nombre del personaje. Dado que los nombres de los caracteres coinciden con las etiquetas de fotograma en nuestro carácterIcono MovieClip podemos usar gotoAndStop para enviar el carácterIcono MovieClip en el cuadro que muestra ese icono de carácter.
Finalmente, agregamos un detector de eventos para comenzar a escribir en la nueva cadena de texto y luego agregamos un escucha CLICK para ejecutar fillText cuando se hace clic en el clip de película.
Ya casi terminamos, solo necesitamos agregar una función que haga que todo comience. Lo haremos con una función pública llamada "startText". Ya que esta es una función pública, pongámosla cerca de la parte superior de la clase RPGText, justo debajo de la bloqueos de texto setter:
public function startText (): void _currentTextBlock = _textBlocks [_currentTextBlockIndex] [TEXT]; characterIcon.gotoAndStop (_textBlocks [_currentTextBlockIndex] [SPEAKER]); addEventListener (Event.ENTER_FRAME, updateText); addEventListener (MouseEvent.CLICK, fillText);
¿Parecer familiar? Este código hace casi exactamente lo mismo que el nextTextBlock función. Establece el texto actual y el icono de carácter, y agrega los escuchas de eventos para updateText y fillText. Dado que esta función solo se ejecuta cuando el texto comienza por primera vez, no debemos preocuparnos por borrar el campo de texto o aumentar el _currentTextBlockIndex como hicimos en nextTextBlock.
Ahora tenemos una forma de acceso público para comenzar el texto. Vamos a ponerlo en uso.
Agregue esta línea al final de la función de constructor de la clase principal:
rpgText.startText ();
Esto es solo llamar a la función startText dentro de la clase RPGText. Eso debería hacer que todo funcione.
Deberías poder probar tu película ahora y ver que todo funcione. Sin embargo, solo falta una cosa: el sonido.
Encuentra (o crea) un sonido para reproducirlo a medida que se escribe el texto. Cuando elija un sonido para esto, hágalo muy corto, ya que este sonido se reproducirá una y otra vez a medida que el texto se active. Un pequeño "boop" o botón de clic funciona mejor para este efecto.
Importe el sonido a la Biblioteca en su archivo Flash, marque "Exportar para ActionScript" y asígnele el nombre de la clase "TypingSound".
Para que se reproduzca este sonido solo necesitamos agregar dos líneas a la clase RPGText. Primero necesitamos instanciar el sonido. Agregue esta línea en la parte superior de la clase debajo de las otras tres variables privadas:
private var _typingSound: Sound = new TypingSound ();
Ahora salta a la función updateText y agrega una línea que realmente reproducirá el sonido cada vez que se actualice el texto (la línea 38 es nueva):
función privada updateText (e: Event): void if (txt.text.length < _currentTextBlock.length) txt.text = _currentTextBlock.substr(0, txt.text.length+1); _typingSound.play(); else removeEventListener(Event.ENTER_FRAME, updateText); fillText();
Eso es todo para la demo. Todo debería funcionar en este punto, pero si quieres integrarlo en un juego, todavía tienes trabajo por delante.
Primero, dependiendo de cómo esté configurado su juego, probablemente querrá sacar los bloques de texto de la clase de documento. Puede tener una clase de escena que usa para configurar las conversaciones individuales que ocurren en su juego, o una clase de cadenas que contiene todo el texto de cada conversación..
En segundo lugar, querrá pensar en cómo y cuándo aparecerá el módulo de texto en su juego. Es posible que desee agregar una animación de interpolación que haga que se deslice hacia adentro y hacia afuera desde la parte inferior cuando una conversación comienza y termina. También querrá estar escuchando cuando termine la conversación, ya sea para ocultar el módulo de texto o comenzar la siguiente conversación.
Ya que estamos verificando para ver si el último bloque de texto se ha alcanzado en el fillText función, usted podría fácilmente agregar algo allí que maneje el final de la conversación.
No estoy incluyendo estos temas en el tutorial porque la forma en que abordes estas cosas será muy específica para tu juego. Esto debería ser suficiente para que comiences.
¡Espero que les haya gustado! Publica un comentario y déjame saber lo que piensas..