Volver al Inicio Microsoft Student Tech Club: Universidad Libre

Tutorial de XNA: Animando un personaje del juego
 

En un videojuego, un personaje como un ser humano, al desplazarse, lo hace caminando o corriendo o saltando. Entonces debemos programar este comportamiento. Los pasos para hacer esto son:

1. Dibujar la animación en una sola imagen, como se ve a continuación. Esta imagen fue tomada de

Platformer Starter Kit 3.1

2. Crear un nuevo proyecto de videojuego desde cero

3. Agregar la imagen al proyecto

4. Ahora agregamos estas instrucciones al código. Son variables de clase.

        //Personaje Animado
        Texture2D PersonajeAnimado;
        //Total de dibujos que tiene el personaje animado
        int TotalDibujosFigura = 10;
        int DibujoFiguraActual = 0;
        //Tamaño del rectángulo que muestra un "frame" del personaje animado
        int rectPersonajeAncho = 96;
        int rectPersonajeAlto = 96;
        //Controla el cambio de un "frame" a otro en el tiempo
        float CuentaTiempo = 0f;
        float CadaCuantoCambia = 100f;
        //Rectángulo que ubica que "frame" del archivo .PNG se dibuja
        Rectangle rectOrigenPersonaje;

5. Cargamos la imagen en LoadContent()

            PersonajeAnimado = Content.Load<Texture2D>("Sprites\\Correr");

6. Y  esta es la parte de la animación. El truco es mostrar un dibujo, luego otro y otro, así sucesivamente dando la sensación que hay movimiento. ¿Y cómo hacemos eso?. Si observamos, la imagen que se carga (la del explorador corriendo), lo que debemos hacer es ubicar un rectángulo que cubra la primera figura y el contenido de ese rectángulo es el que se muestra. Luego se desplaza el rectángulo a la segunda figura y se muestra esa, así sucesivamente hasta que termine en la última figura y vuelve a la figura inicial en un ciclo sin fin.

Esa lógica debe ir, por supuesto, en Update()

           //Acumula los milisegundos que lleva ejecutando el juego  
           CuentaTiempo += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
           //Si el acumulado pasa de determinado tiempo
           if (CuentaTiempo > CadaCuantoCambia)  
           {  
               //Pasa al siguiente "frame"
               DibujoFiguraActual++;
               //Se controla no pasarse de todos los "frames" del personaje
               if (DibujoFiguraActual > TotalDibujosFigura - 1)
                   DibujoFiguraActual = 0;
               //Acumulador de tiempo a cero  
               CuentaTiempo = 0f;  
           }
           //Determina donde ubicar el rectángulo para el siguiente "frame"
           rectOrigenPersonaje = new Rectangle(this.DibujoFiguraActual * this.rectPersonajeAncho, 0, this.rectPersonajeAncho, this.rectPersonajeAlto);

7. Dibujar la animación en Draw()

            spriteBatch.Begin();
            /* Los parámetros son:
             * 1. Textura a cargar (todo el archivo .png que tiene la animación).
             * 2. Posición donde colocar el sprite "animado"
             * 3. Rectángulo origen. Carga el "frame" a mostrar que luego es dibujado en el rectángulo destino
             * 4. Color de fondo
             * 5. Rotación
             * 6. Origen
             * 7. Escala
             * 8. Efecto del sprite. Reflejo horizontal.
             * 9. Profundidad en el que se dibuja */
            Vector2 Origen = new Vector2(0f, 0f);
            Vector2 Posicion = new Vector2(0f, 0f);
            spriteBatch.Draw(PersonajeAnimado, Posicion, rectOrigenPersonaje, Color.White, 0.0f, Origen, 1.0f, SpriteEffects.None, 0.0f);
            spriteBatch.End();

8. Este es el código completo

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;
namespace Animacion
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        //Personaje Animado
        Texture2D PersonajeAnimado;
        //Total de dibujos que tiene el personaje animado
        int TotalDibujosFigura = 10;
        int DibujoFiguraActual = 0;
        //Tamaño del rectángulo que muestra un "frame" del personaje animado
        int rectPersonajeAncho = 96;
        int rectPersonajeAlto = 96;
        //Controla el cambio de un "frame" a otro en el tiempo
        float CuentaTiempo = 0f;
        float CadaCuantoCambia = 100f;
        //Rectángulo que ubica que "frame" del archivo .PNG se dibuja
        Rectangle rectOrigenPersonaje;
        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
            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);
            // TODO: use this.Content to load your game content here
            PersonajeAnimado = Content.Load<Texture2D>("Sprites\\Correr");
        }
        /// <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();
            // TODO: Add your update logic here
            //Acumula los milisegundos que lleva ejecutando el juego  
            CuentaTiempo += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            //Si el acumulado pasa de determinado tiempo
            if (CuentaTiempo > CadaCuantoCambia)
            {
                //Pasa al siguiente "frame"
                DibujoFiguraActual++;
                //Se controla no pasarse de todos los "frames" del personaje
                if (DibujoFiguraActual > TotalDibujosFigura - 1)
                    DibujoFiguraActual = 0;
                //Acumulador de tiempo a cero  
                CuentaTiempo = 0f;
            }
            //Determina donde ubicar el rectángulo para el siguiente "frame"
            rectOrigenPersonaje = new Rectangle(this.DibujoFiguraActual * this.rectPersonajeAncho, 0, this.rectPersonajeAncho, this.rectPersonajeAlto);
            base.Update(gameTime);
        }
        /// <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.CornflowerBlue);
            // TODO: Add your drawing code here
            spriteBatch.Begin();
            /* Los parámetros son:
             * 1. Textura a cargar (todo el archivo .png que tiene la animación).
             * 2. Posición donde colocar el sprite "animado"
             * 3. Rectángulo origen. Carga el "frame" a mostrar que luego es dibujado en el rectángulo destino
             * 4. Color de fondo
             * 5. Rotación
             * 6. Origen
             * 7. Escala
             * 8. Efecto del sprite. Reflejo horizontal.
             * 9. Profundidad en el que se dibuja */
            Vector2 Origen = new Vector2(0f, 0f);
            Vector2 Posicion = new Vector2(0f, 0f);
            spriteBatch.Draw(PersonajeAnimado, Posicion, rectOrigenPersonaje, Color.White, 0.0f, Origen, 1.0f, SpriteEffects.None, 0.0f);
            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}

9. Y el resultado es una figura en movimiento:

 

Volver al Inicio Célula Microsoft. Universidad Libre