Mostrar Texto al Estilo de una máquina de Escribir – AutoTyping – XNA


Voy a enseñarles un pequeño ejemplo de mostrar un texto al estilo máquina de escribir, o al estilo de los Juegos de RPG donde se va mostrando letra por letra a cierta Velocidad, o al estilo de los terminales de las naves espaciales que van mostrando mensajes de advertencia por sí solos.

Cambiando letra y adicionando sonidos después podemos obtener algo mejor que esto:

El método es muy sencillo, solo debemos tomar el mensaje original, e ir mostrando el mensaje añadiendolé letra por letra cada cierto tiempo, teniendo un efecto tardío al escribir.

Para que me entiendan mejor, he creado una función llamada AutoTyping, que recibe como parámetro un objeto GameTime para poder controlar el lapso de tiempo en que se mostrará cada carácter:

Protected void AutoTyping(GameTime gameTime)
{
  segundos += Convert.ToDecimal(gameTime.ElapsedGameTime.TotalSeconds);
  if (segundos < duracion)
  {
     return;
  }
  else
  {
    segundos = 0;
    if (i < mensaje.Length)
    {
       resultado = mensaje.Substring(0, i);
       i++;
    }
 }
}

 La función solo acaba cuando la variable i, va a tener como valor la longitud del texto que vamos a mostrar, si no la tiene, la variable resultado que és la que vamos a mostrar en la pantalla, va a tener un pedazo (substring) del mensaje original, desde la posición 0 hasta donde tenga como valor la variable i.

Para mostrar el texto, solo debemos indicar cual va a ser la duración en la que se van a mostrar los caracteres.

Como toque final, adiciono la función para adicionar saltos de línea a un texto, lo que inglés le dicen Wrap, la función la encontré en la Wiki de XNA: http://www.xnawiki.com/index.php?title=Basic_Word_Wrapping.

Todo el código queda así:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.Text;

namespace AutoTyping
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SpriteFont fuente;
        Int32 i;
        String mensaje;
        String resultado = "";
        Decimal segundos;
        Decimal duracion;
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            mensaje = "WARNING!!...Este es un ejemplo de un texto auto tipeado al estilo de los Viejos Computadores " +
                "La extrana y exótica Menzoberranzan, la gran ciudad de la Antípoda Oscura, " +
                "fundada hace milenios por los elfos oscuros tras su marcha del mundo exterior. " +
                "Es la morada del héroe de el Valle del Viento Helado, Drizzt DoUrden." +
                "Drizzt, el joven príncipe de una de las casa regentes, llega a la madurez en el mundo " +
                    "cruel y despiadado de su raza, donde el único rayo de esperanza es su maestro de armas, Zaknafein, " +
                    "quien le enseña cómo? y para qué ? usar una espada.";
            i = 0;
            duracion = 0.02M;
            base.Initialize();
        }
        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            fuente = Content.Load<SpriteFont>("fuente");
            mensaje = WrapText(fuente, mensaje, 600);
            // TODO: use this.Content to load your game content here
        }
        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            AutoTyping(gameTime);
            // TODO: Add your update logic here
            base.Update(gameTime);
        }
        protected void AutoTyping(GameTime gameTime)
        {
            segundos += Convert.ToDecimal(gameTime.ElapsedGameTime.TotalSeconds);
            if (segundos < duracion)
            {
                return;
            }
            else
            {
                segundos = 0;
                if (i < mensaje.Length)
                {
                    resultado = mensaje.Substring(0, i);
                    i++;
                }
            }
        }
        public String WrapText(SpriteFont spriteFont, String text, float maxLineWidth)
        {
            String[] words = text.Split(' ');
            StringBuilder sb = new StringBuilder();
            float lineWidth = 0f;
            float spaceWidth = spriteFont.MeasureString(" ").X;
            foreach (String word in words)
            {
                Vector2 size = spriteFont.MeasureString(word);
                if (lineWidth + size.X < maxLineWidth)
                {
                    sb.Append(word + " ");
                    lineWidth += size.X + spaceWidth;
                }
                else
                {
                    sb.Append("\n" + word + " ");
                    lineWidth = size.X + spaceWidth;
                }
            }
            return sb.ToString();
        }
        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);
            spriteBatch.Begin();
            spriteBatch.DrawString(fuente, resultado, new Vector2(10, 100), Color.White);
            spriteBatch.End();
            // TODO: Add your drawing code here
            base.Draw(gameTime);
        }
    }
}

 

 
 

 

Deseas comentar o sugerir algo?

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s