| 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

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 |