Advertisement
  1. Code
  2. Games

Crea un sistema de texto de estilo RPG para tu próximo juego

Scroll to top
Read Time: 15 min

Spanish (Español) translation by Esther (you can also view the original English article)

En este tutorial vamos a crear un sistema de texto similar al que se ve en muchos juegos de rol. Nuestra clase mostrará dinámicamente un icono para los personajes mientras hablan, y escribirá cada bloque de texto letra por letra.

Avance del resultado final

Este es un ejemplo del sistema de texto que vamos a crear:

Paso 1: Configurar el archivo Flash

Crea 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.

Flash file setup

Paso 2: Añadir una imagen de fondo

Lo más probable es que muestre el módulo de texto sobre una imagen o animación de su juego. Para esta demostración estoy utilizando una imagen que he creado con algunos de los personajes de mis juegos de pie en un campo de nieve.

Coloca tu imagen de fondo en una capa llamada "fondo".

Background image or animation

Paso 3: Crear el RPGText MovieClip

Crea un nuevo MovieClip en el escenario (Insert > MovieClip) llamado "RPGText".

En las Propiedades del Símbolo marca "Exportar para Actionscript" y establece el nombre de la clase como "RPGText". Utilizaremos este nombre de clase más tarde para vincular el código a este MovieClip.

RPGText Symbol Properties

Haz clic en OK. Si ves una advertencia aquí de que la definición de la clase no pudo ser encontrada, está bien. Significa que no hay ningún código para enlazar con este símbolo (todavía).

Dale a tu MovieClip el nombre de instancia "rpgText". Recuerda que cuando hablo de "RPGText" (en mayúsculas) me refiero a la clase (o MovieClip); "rpgText" (en minúsculas) es el nombre de una instancia de esa clase.

Paso 4: Añadir un fondo de panel de texto

Dibuja un rectángulo dentro de tu nuevo RPGText MovieClip. Este será el fondo para los iconos de los personajes y la burbuja de diálogo. Diséñalo como quieras, pero debe abarcar todo el ancho de tu película y ser lo suficientemente corto como para no cubrir demasiado tu juego.

Hice el mío de 500px de ancho (para que coincida con mi película) y 100px de alto. Lo rellené con un degradado de #666666 a #999999 (de gris oscuro a gris más claro).

Background Rectangle

Consejo rápido: para dibujar un rectángulo de un tamaño determinado, selecciona la herramienta rectángulo y pulsa Alt en el escenario. Aparecerá un cuadro de diálogo en el que podrás introducir las dimensiones de tu rectángulo.

Paso 5: El icono del personaje MovieClip

Crea una nueva capa dentro del MovieClip de RPGText llamada "icono". Crea un nuevo MovieClip en esta capa llamado "characterIcon" y dale el nombre de instancia "characterIcon".

Dentro del MovieClip characterIcon crear dos nuevas capas: "iconos" y "etiquetas". La capa de iconos contendrá todos los iconos de tus personajes (cada uno en su propio fotograma clave) y la capa de etiquetas contendrá las etiquetas de los fotogramas que utilizaremos para mostrar los personajes en el momento adecuado.

Importa (o dibuja en Flash) un icono para cada uno de los personajes de tu juego que vayan a hablar. Para esta demostración hice un JPG de 75x75px para cada uno de mis personajes. Añade los iconos a la capa de iconos, haciendo un nuevo fotograma clave para cada personaje. El orden en el que aparecen no es importante, pero asegúrate de que cada icono está colocado en x:0, y:0 para que no parezca que saltan cuando cambias de personaje.

Character Keyframes

Paso 6: Añadir etiquetas al marco

Ahora crea un nuevo fotograma clave en cada cuadro de tu capa de etiquetas. Una forma rápida de hacerlo es seleccionar todos los fotogramas y pulsar F6.

Selecciona cada fotograma clave de etiqueta uno por uno y añade una etiqueta de fotograma que corresponda al nombre del personaje que aparece en ese fotograma. Si añades algunos fotogramas vacíos (F5) entre tus fotogramas clave, será más fácil leer las etiquetas de los fotogramas, sólo asegúrate de que los fotogramas clave de las etiquetas se mantengan alineados con los fotogramas clave de los iconos.

Adding Frame Labels

Asegúrate de que cada una de tus etiquetas tiene un nombre único. Si tienes dos personajes con el mismo nombre, tendrás que diferenciarlos de alguna manera ('Juan_L' y 'Juan_K', por ejemplo).

Paso 7: Dibujar la burbuja de diálogo

Vuelve al MovieClip de RPGText y crea una nueva capa llamada "textBackground".

Dibuja una burbuja de diálogo. Yo dibujé una burbuja sencilla con esquinas cuadradas, pero puedes hacer que la tuya tenga el aspecto que quieras. Hazla lo suficientemente grande como para que llene la mayor parte del rectángulo de fondo y quede bien junto a los iconos de tus personajes.

Selecciona tu bocadillo y conviértelo en un MovieClip (Modify > Convert to Symbol). Ahora que es un MovieClip podemos añadirle un filtro de sombra. Yo puse el mío en negro, 50% de intensidad, 5px de desenfoque y 1px de distancia.

Speech Bubble Graphic

Paso 8: Añadir el campo de texto dinámico

Crea una nueva capa en el MovieClip de RPGText llamada "texto". Utilice la herramienta de texto para dibujar un cuadro de texto. Haz que encaje justo dentro de los bordes del gráfico de la burbuja de diálogo.

Hazlo un campo de texto dinámico de varias líneas con el nombre de instancia "txt". Recuerda incrustar la fuente si no estás usando el texto del sistema. Yo estoy usando Courier de 13pt.

Dynamic Text Field Properties

Paso 9: Añadir el botón Siguiente

Necesitamos una forma de que el jugador avance al siguiente bloque de texto cuando haya terminado de leer. Añadamos un pequeño botón "siguiente" en la esquina.

Crea una nueva capa en el MovieClip de RPGText llamada "botón". Añade un nuevo símbolo de botón llamado "b_next". Diseña los cuatro estados de tu botón como quieras. He utilizado una pequeña flecha hacia abajo como símbolo del botón porque lo veo en muchos juegos y asumo que los jugadores están familiarizados con él.

Coloca tu botón en la esquina inferior derecha, encima de tu burbuja de discurso. No te preocupes por darle un nombre de instancia. Más adelante te explicaré por qué.

Complete RPGText MovieClip

Paso 10: Crear la clase documental

Crea un nuevo archivo de Actionscript llamado "Main.as" y añade este código para crear el shell vacío para la clase:

Establece Main como la clase de documento en tu archivo Flash. Si quieres un repaso rápido sobre el uso de una clase de documento, este consejo rápido de Michael Williams es una de las mejores explicaciones que he visto.

Paso 11: Añadir los bloques de texto

Si estás usando esto en un juego probablemente elegirás ponerlo en otro lugar, pero por ahora lo añadiremos a la clase Document. Añade este código a la función constructora de la clase Main:

Aquí estamos creando un array bidimensional (un array que contiene otros arrays) para contener el script de nuestra escena. Antes de cambiar nada, echa un vistazo a cómo está estructurado. Cada array 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 están listados en el orden en que aparecerán en la escena.

La última línea solo envía el array textBlocks al MovieClip rpgText (recuerda que "rpgText" es el nombre de instancia del MovieClip RPGText en el escenario). Más adelante hablaremos de esto.

Sigue adelante y edita esta sección para que se ajuste a tu escena. Ten mucho cuidado de que los nombres de los personajes se correspondan exactamente con los nombres que utilizaste para las etiquetas de los fotogramas en el MovieClip characterIcon.

Paso 12: Crear la clase RPGText

Por fin estamos listos para empezar a escribir el código de la clase RPGText.

Crea un nuevo archivo de Actionscript llamado "RPGText.as" y añade este código:

Esto es solo un shell básico para la clase. No hace nada todavía, pero vamos a echar un vistazo a lo que hay:

  • Las primeras líneas son solo para importar algunas de las clases que vamos a necesitar.
  • En la declaración de la clase estamos extendiendo la clase MovieClip. Necesitamos hacerlo porque esta clase está vinculada al RPGText MovieClip en la Biblioteca (ver Paso 3).
  • A continuación, tenemos dos constantes, SPEAKER y TEXT que utilizaremos para obtener el nombre del orador y el texto del array textBlocks que configuramos en el paso anterior.
  • La variable _currentTextBlockIndex mantendrá un registro del bloque de texto que estamos mostrando actualmente.
  • _currentTextBlock contendrá el texto actual.c
  • _textBlocks contendrá todo el array de bloques de texto.
  • Por último, está el constructor de la clase vacía.

(Nota: Estoy usando el guión bajo en mis nombres de variables para indicar variables privadas).

Paso 13: La función textBlocks Setter

Como nuestra variable _textBlocks es privada, necesitaremos una forma de acceder a esa variable desde la clase Main, donde estamos configurando los bloques de texto. Lo haremos creando una función "setter". Añade esto a la clase RPGText justo debajo de la función constructora:

Lo bueno de los setters 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 Main en el paso 11:

Paso 14: Añadir la función updateText

Añade esta función a la clase RPGText:

Esta es la funcionalidad principal de la clase, donde se produce la escritura letra a letra. Echemos un vistazo más de cerca a lo que sucede aquí:

  • Línea 27: Esta función acepta un Evento como parámetro porque la llamaremos usando un evento ENTER_FRAME.
  • Línea 28: Comparamos la longitud (número de caracteres) actualmente en el campo de texto txt con el número de caracteres en la cadena _currentTextBlock.
  • Línea 29: Si hay menos caracteres en el campo de texto, entonces usamos el método substr para obtener todos los caracteres desde el principio de _currentTextBlock hasta uno más que el número de caracteres actualmente en el campo de texto. Ponemos todos esos caracteres en el campo de texto, lo que tiene el efecto de añadir un carácter más al final del texto en el campo de texto.
  • Línea 31: Si hay el mismo número de caracteres en el campo de texto que en la cadena _currentTextBlock, elimina el evento ENTER_FRAME que llama a esta función.
  • Línea 32: Llama a la función fillText. Esta función la escribiremos en el siguiente paso.

Paso 15: Añadir la función fillText

Añade esta función a la clase RPGText:

El propósito principal de esta función es llenar el campo de texto txt con el texto del _currentTextBlock (línea 37). Si dejamos que la animación se reproduzca, la función updateText debería encargarse de eso, pero es bueno asegurarse de que nada salió mal. También podemos conectar esta función a nuestro botón "siguiente" para permitir a los jugadores saltarse la animación del texto y rellenar inmediatamente el campo de texto con el bloque de texto completo.

Observa que esta función acepta un MouseEvent como argumento, pero establecemos su valor por defecto en null. Esto nos permite utilizar esta función con un MouseEvent listener, ya que aceptará el evento. Como le damos al evento un valor por defecto también podemos llamar a la función sin enviar un evento como hacemos al final de la función updateText.

Después de llenar el campo de texto, hacemos una comprobación para ver si este es el último bloque de texto en el array (si el _currentBlockIndex es menor que el número de elementos en el array _textBlock). Si no es así, añadimos un escuchador CLICK para activar una función llamada nextTextBlock que escribiremos a continuación.

Paso 16: Sobre ese Click Listener

¿Recuerdas cuando creamos el botón "siguiente" y te dije que no te preocuparas por darle un nombre de instancia? ¿Te diste cuenta en el último paso de cómo adjuntamos el escuchador CLICK a todo el MovieClip de RPGText en lugar de al botón? Esto hace que el jugador pueda hacer clic en cualquier parte del MovieClip para avanzar el texto. Realmente ni siquiera necesitamos el botón, pero me gusta poner uno para que haya alguna indicación de que se hace clic para avanzar el texto.

Por supuesto, esto es solo una preferencia personal mía. Si quieres, puedes darle al botón un nombre de instancia y adjuntar el oyente de CLICK al botón en su lugar. Simplemente encuentro que el área de golpeo más grande es más fácil de usar.

Paso 17: Añadir la función nextTextBlock

De vuelta al trabajo. Añade esta función a la clase RPGText:

Las tres primeras líneas son bastante simples. Elimina el MouseEvent listener, limpia el campo de texto, e incrementa la var _currentTextBlockIndex para apuntar al siguiente bloque de texto.

La línea 47 utiliza la constante TEXT para obtener la cadena de texto actual del array _textBlocks y asignarla a _currentTextBlock.

A continuación utilizamos la constante SPEAKER para obtener el nombre del personaje. Como los nombres de los personajes coinciden con las etiquetas de los fotogramas de nuestro MovieClip characterIcon, podemos utilizar gotoAndStop para enviar el MovieClip characterIcon al fotograma que muestra ese icono de personaje.

Finalmente, añadimos un escuchador de eventos para empezar a escribir en la nueva cadena de texto y luego añadimos un escuchador CLICK para ejecutar fillText cuando se haga clic en el MovieClip.

Paso 18: Añadir la función startText

Ya casi hemos terminado, solo nos falta añadir una función que haga que todo empiece. Lo haremos con una función pública llamada "startText". Como es una función pública, la pondremos cerca de la parte superior de la clase RPGText, justo debajo del setter de textBlocks:

¿Te resulta familiar? Este código hace casi lo mismo que la función nextTextBlock. Establece el texto actual y el icono del carácter, y añade las escuchas de eventos para updateText y fillText. Dado que esta función solo se ejecuta cuando el texto comienza por primera vez, no tenemos que preocuparnos de borrar el campo de texto o incrementar el _currentTextBlockIndex como hicimos en nextTextBlock.

Paso 19: Invocar la función startText

Ahora tenemos una forma accesible al público de empezar el texto. Vamos a ponerlo en práctica.

Añade esta línea al final de la función constructora de la clase Main:

Esto es solo llamar a la función startText dentro de la clase RPGText. Eso debería poner todo en marcha.

Paso 20: Añadir sonido

Ahora deberías poder probar tu película y ver que todo funciona. Solo falta una cosa: el sonido.

Encuentra (o crea) un sonido que se reproduzca mientras se escribe el texto. Cuando elijas un sonido para esto, mantenlo muy corto, ya que este sonido se reproducirá una y otra vez mientras el texto se escribe. Un pequeño "boop" o el clic de un botón funciona mejor para este efecto.

Importa el sonido a la Biblioteca en tu archivo Flash, marca "Exportar para Actionscript" y dale el nombre de clase "TypingSound".

Sound Export Settings

Para conseguir que este sonido se reproduzca solo tenemos que añadir dos líneas a la clase RPGText. Primero necesitamos instanciar el sonido. Añade esta línea en la parte superior de la clase debajo de las otras tres variables privadas:

Ahora baja a la función updateText y añade una línea que realmente reproduzca el sonido cada vez que el texto se actualice (la línea 38 es nueva):

Paso 21: Llevarlo más lejos

Eso es todo para la demo. Todo debería funcionar en este punto, pero si quieres integrar esto en un juego, todavía tienes algo de trabajo por delante.

En primer lugar, dependiendo de cómo esté configurado tu juego, probablemente querrás sacar los bloques de texto de la clase Document. Puede que tengas una clase Scene que utilices para configurar las conversaciones individuales que ocurren en tu juego, o una clase Strings que contenga todo el texto de cada conversación.

En segundo lugar, deberás pensar en cómo y cuándo aparecerá el módulo de texto en tu juego. Puede que quieras añadir una animación de interpolación que haga que se deslice hacia dentro y hacia fuera desde la parte inferior cuando empiece y termine una conversación. También querrás estar atento a cuando la conversación termine, para ocultar el módulo de texto o iniciar la siguiente conversación.

Dado que ya estamos comprobando si se ha alcanzado el último bloque de texto en la función fillText, se podría añadir fácilmente algo allí que gestione el final de la conversación.

No incluyo estos temas en el tutorial porque la forma de hacer estas cosas será muy específica para tu juego. Sin embargo, esto debería ser suficiente para empezar.

¡Espero que te haya gustado! Publica un comentario y hazme saber lo que piensas.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.