Volver al Inicio Microsoft Student Tech Club: Universidad Libre

Tutorial de XNA: Agregar el protagonista a nuestro juego
 

Es el turno de agregar al juego a nuestro héroe, es decir, al protagonista, aquel que controlamos con el teclado, con el mouse o con el gamepad. Debemos tener presente que si desarrollamos en XNA, el juego puede ser llevado a la consola XBOX y allí solo hay gamepad como se ve en la imagen.

Gamepad

Paso 0: ¿En que consiste el juego?

Antes de empezar, debemos saber en que consiste el juego, para este tutorial se trata de un cañón o lanzador que se encarga de destruir chatarra espacial porque se ha convertido en un problema grave de contaminación espacial.

Paso 1: ¿Cómo se comportará nuestro protagonista?

Es un lanzador estacionario, el cual varía su ángulo de lanzamiento y a determinada orden, lanzará la bala o misil. Luego la animación del protagonista es variación del ángulo de salida del misil.

Paso 2: Buscando una imagen acorde a la animación

Nuevamente en www.bing.com podemos buscar una imagen que nos sirva en esta tarea. Y se encuentra esta, la cual esta bien porque requerimos una base (inmóvil) y el lanzador de balas (que adaptaremos para que lance misiles)

Paso 3: Convirtiendo las imágenes

Dividimos la imagen en dos partes (use por ejemplo un capturador de pantalla o algún software de manipulación de imágenes) y cada parte modifíquela con Paint .NET para archivos .TGA con transparencias. Así deben lucir:

Así deben quedar los archivos, en formato .TGA

Paso 4: Ahora los movemos al proyecto del juego que se está haciendo.

Paso 5: Generar la clase que soporta los actores del juego

Los actores (héroe, enemigos, balas) del juego son objetos, por tanto debemos generar una clase que soporte ese tipo de objetos, a la que llamaremos ObjetosJuego

En esa clase nueva agregamos todas las librerías que importa o usa Game1.cs y escribimos el esqueleto de la clase en sí.

Este es el código

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 PrimerJuego
{
   class ObjetosJuego
   {
   }
}

Paso 6: ¿Qué debe ir en la clase que soporta los actores del juego?

Debemos recordar que todos los protagonistas del juego reciben el nombre de "sprite" (un término manejado por la industria).

En la nueva clase ObjetosJuego se añaden las propiedades que tendrá nuestro "sprite" lanzador y se genera el constructor por defecto, así queda el código de la clase

Este es el código:

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 PrimerJuego
{
   class ObjetosJuego
   {
      public Texture2D sprite; //La textura (o imagen) que tendrá el sprite
      public Vector2 posicion; //En que punto se encuentra ubicado el sprite
      public Vector2 centro; //El centro por donde gira el lanzador
      public float rotacion; //Angulo de rotación del lanzador

      //Constructor
      public ObjetosJuego(Texture2D textura)
      {
         sprite = textura; //Recibe la textura por parámetro
         posicion = Vector2.Zero; // Posición [0,0] por defecto
         rotacion = (float) 0.0; //Rotación 0.0 en radianes por defecto
         centro = new Vector2(sprite.Width / 2, sprite.Height / 2); //El centro del sprite
      }
   }
}

Paso 7: Hacemos uso de la clase que soporta los actores.

Volvemos de nuevo a Game1.cs y agregamos las dos variables objeto que manejarán nuestro lanzador.

Paso 8: Se cargan las texturas de los actores

Ahora debemos inicializar esas variables con las texturas del lanzador y la base y eso se hace en LoadContent()

Paso 9: Se muestran las texturas de los actores.

Por último es mostrar nuestro protagonista en pantalla, para eso vamos al método Draw y escribimos el siguiente código

El código completo de Game1.cs es este que se presenta a continuación

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 PrimerJuego
{

/// <summary>
/// This is the main type for your game
/// </summary>

public class Game1 : Microsoft.Xna.Framework.Game
{

GraphicsDeviceManager graphics;
SpriteBatch spriteBatch; //Contenedor de los sprite
Texture2D Fondo; //Variable de tipo textura que tendrá el fondo
Rectangle rectFondo; //Un rectángulo donde estará la textura del fondo

ObjetosJuego lanzador; //El lanzador
ObjetosJuego baselanzador; //Base del lanzador

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

//Utiliza genéricos <> por eso el uso de <> En C++ se llaman plantillas. Content carga el contenido binario.
Fondo = Content.Load<Texture2D>("Imagenes\\FondoJuego");

//El rectángulo en el que estará contenido el fondo
rectFondo = new Rectangle(0, 0, graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height);

//Cargar e inicializar el Lanzador
lanzador = new ObjetosJuego(Content.Load<Texture2D>("Imagenes\\Lanzador")); //No es necesaria la extensión .tga
lanzador.posicion = new Vector2(160, 530); //Posición del lanzador

//Cargar e inicializar la base
baselanzador = new ObjetosJuego(Content.Load<Texture2D>("Imagenes\\Base")); //No es necesaria la extensión .tga
baselanzador.posicion = new Vector2(70, 560); //Posición de la base del lanzador

}

/// <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

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

//Se inicia el spritebatch (Entre Begin y End se dibuja en cada unidad de tiempo los sprites)
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

//Dibujar el fondo combinando el color blanco con el fondo
spriteBatch.Draw(Fondo, rectFondo, Color.White);

//Dibuja la base del lanzador combinando con blanco
spriteBatch.Draw(baselanzador.sprite, baselanzador.posicion, Color.White);

/* Dibuja el lanzador como tal, estos son los parámetros
* Parámetro 1: El sprite del lanzador
* Parámetro 2: La posición del lanzador
* Parámetro 3: null porque es solo una imagen (no una sucesión de estas)
* Parámetro 4: Color.White, combinación de color
* Parámetro 5: Angulo de rotación por defecto
* Parámetro 6: Centro, el centro del sprite para girarlo después
* Parámetro 7: Escala a dibujar
* Parametro 8: Dibujar tal como es el sprite (no reflejo vertical ni horizontal)
* Parámetro 9: Ponerlo en la capa superior */
spriteBatch.Draw(lanzador.sprite, lanzador.posicion, null, Color.White, lanzador.rotacion, lanzador.centro, 0.6f, SpriteEffects.None, 0);


//Finaliza el "ciclo" de los sprite
spriteBatch.End();

base.Draw(gameTime);

}

}

}

Al ejecutar, este es el resultado

Nota aclaratoria: La rutina Draw() es ejecutada por XNA cuando se determina que hay que dibujar un nuevo "frame" (Fotograma).

Volver al Inicio Célula Microsoft. Universidad Libre