XNA – Inicio, Cargar, Mover y Disparar!


Para los que no saben XNA es una API proporcionada por Microsoft, para el desarrollo de video juegos, para PC, XBOX y Zune.

Para iniciar vamos a ver como se crea un proyecto y una pequeña aplicación para mostrar más o menos que es XNA y cómo funciona.

–          Descargamos XNA (Actualmente ya va en la versión 3 punto algo :P)

–          Instalamos XNA, antes de hacerlo debemos asegurarnos de tener Instalado Visual Studio 2005 o superior, puede ser el Express, pero debe ser el lenguaje C#

–          Y que nuestro PC tenga una tarjeta de video que soporte Pixel Shader 1.1 o superior o que sea del año 2003 o superior, así que si no tienes una tarjeta de video, a empezar a ahorrar para comprarse una.

Después de haber instalado todo, empezamos  un nuevo proyecto de XNA en Visual Studio ( En mi caso tengo Visual Studio 2008)

 

Cuando creamos un proyecto, se crean archivos en el proyecto, entre los archivos tenemos una clase llamada Game1, que es la que contendrá el flujo de nuestro juego, también se crea un icono, que será el que por defecto tendrá el juego, y una imagen que servirá para cuando enviemos nuestro juego al XNA Creator Club Online o al XBOX Live:

 

Si presionamos F5 o ejecutamos el código, nos muestra una pantalla con color azul clarito ( a menos que tengamos un error por causa de la tarjeta gráfica):

 

La clase Game1.cs contiene el siguiente código generado:

–          Game1(): El constructor de la clase

–          Initialize():  En este método debemos inicializar las variables y la lógica del juego, como número de vidas, puntajes, etc.

–          LoadContent(): En este método cargamos el contenido de la carpeta Content al juego, como por ejemplo imágenes (Sprites), Sonidos, videos, fuentes, etc.

–          UnloadContent(): Aquí debemos descargar el contenido cargado en Load Content() para liberar recursos

–          Update(GameTime): Este es el método más importante, pues se va a llamar cada instante y será el que llevará el flujo del juego, aquí debemos llamar los demás métodos que ejecutan la lógica del juego, como manejo de colisiones, manejo del teclado, Control o el Mouse, etc.

–          Draw(GameTime):  Este método es usado para dibujar cada cambio en el juego, aquí dibujamos las imágenes, la posición y la interacción de las imágenes.

El ciclo de vida de los Juegos en XNA es explicado en la siguiente imagen:

Manos a la Obra!!!

Si no les gusto el fondo, podemos en el método Draw, cambiar el color del fondo:

GraphicsDevice.Clear(Color.Black);

Para que la pantalla quede en Full Screen , en el constructor escribimos lo siguiente, la resolución es de 1280×720, pero pueden modificarla a su gusto:

public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            this.graphics.PreferredBackBufferWidth = 1280;
            this.graphics.PreferredBackBufferHeight = 720;
            this.graphics.IsFullScreen = true;
        }

Y para el manejo del teclado, hacemos lo siguiente para cuando presionemos la tecla Escape se salga de la aplicación, en el método Update:

KeyboardState teclado;
teclado = Keyboard.GetState();
if (teclado.IsKeyDown(Keys.Escape))
   {
     this.Exit();
    }

Ahora vamos a cargar un Sprite  o una imagen.

Encontré este avión en internet, que será nuestro actor, para cargar una imagen seguimos los siguientes pasos:

–          Obtenemos una imagen, que tenga el fondo transparente, para evitar que solo se dibuje la imagen y no el fondo

–          Adicionamos nuestra imagen en el proyecto, en la carpeta Content:

 

–          La imagen que vamos a cargar en este momento es:

 

–          Ahora que tenemos la imagen en la carpeta Content, proseguimos a crear las variables necesarias para el movimiento del avión

–          Creamos una variable tipo Texture2D que es la que guardará los datos de la imagen:

Texture2D avion;

–          Creamos dos variables tipo Int32 para la posición X y Y del avión:

Int32 PosAvioX = 0;
Int32 PosAvionY = 0;

–          Creamos una variable tipo Int32 para la velocidad del avión:

Int32 velocidadBala = 10;

–          En  el método LoadContent, relacionamos la imagen del avión a la textura:

avion = Content.Load<Texture2D>(«avion»);

 Es muy fácil cargar una imagen, solo debemos usar la clase ContentManager, y llamar el                método Load, este método genérico carga un archivo de la carpeta content, el “avion” es el nombre de la imagen o el archivo.

 –          Inicializamos la posición del avión en el método Initialize para que aparezca en la mitad de la pantalla en la parte izquierda:

PosAvionY = Window.ClientBounds.Height / 2;

 –          En el método Draw, dibujamos la imagen en la pantalla, para hacerlo usamos la clase spriteBatch que ya ha sido creada, para dibujar una imagen, hay que llamar el método Begin, luego el método Draw donde especificamos la posición en la pantalla y el tamaño de la imagen, luego llamamos el método End:

spriteBatch.Begin();
spriteBatch.Draw(avion, new Rectangle(PosAvionX, PosAvionY, avion.Width, avion.Height), Color.White);
spriteBatch.End();

–          Si Ejecutamos:

 

Ahora, para mover el Sprite por la pantalla, hacemos uso de las variables PosAvionX y PosAvionY, en el método Update, verificamos que se estén oprimiendo las teclas arriba, abajo, izquierda o derecha, y si se están oprimiendo, restamos o sumamos a las variables de Posición, para que el método Draw este actualizando la posición del Avión:

if (teclado.IsKeyDown(Keys.Right))
   {
     PosAvionX = PosAvionX + velocidad;
   }
if (teclado.IsKeyDown(Keys.Left))
   {
     PosAvionX = PosAvionX - velocidad;
   }
if (teclado.IsKeyDown(Keys.Up))
   {
     PosAvionY = PosAvionY - velocidad;
   }
if (teclado.IsKeyDown(Keys.Down))
   {
     PosAvionY = PosAvionY + velocidad;
   }

Si ejecutamos:

 

Límites!!!

Pero que sucede ¿si movemos la imagen por fuera de la pantalla? La imagen desaparece, para evitar eso, vamos a limitar el movimiento del avión, para que se mueva solo dentro de la pantalla, solo debemos agregar unas validaciones en el método Update cada vez que se mueva la imagen. Ahora el método Update quedará así:

if (teclado.IsKeyDown(Keys.Right))
{
   if (PosAvionX <= (Window.ClientBounds.Width - avion.Width))
       {
         PosAvionX = PosAvionX + velocidad;
       }
}
if (teclado.IsKeyDown(Keys.Left))
{
   if (PosAvionX >= 0)
     {
          PosAvionX = PosAvionX - velocidad;
      }
}
if (teclado.IsKeyDown(Keys.Up))
{
   if (PosAvionY >= 0)
     {
           PosAvionY = PosAvionY - velocidad;
      }
}
if (teclado.IsKeyDown(Keys.Down))
{
    if (PosAvionY <= (Window.ClientBounds.Height - avion.Height))
      {
           PosAvionY = PosAvionY + velocidad;
       }
}

Para el límite del eje X, el avión no se puede mover a una posición menor a 0, ni tampoco a una posición mayor al ancho de la pantalla – el ancho del avión, porque debemos recordar que el eje X y Y del avión se encuentran en la parte superior – izquierda de la imagen. Para el eje Y es lo mismo.

En pocas palabras, en la siguiente imagen se intenta explicar mejor las coordenadas de la pantalla:

 

Disparos!!!

Para agregar disparos, vamos a hacerlo de la manera más fácil: el avión solo podrá disparar 1 una sola bala, cuando la bala se salga de la pantalla quedará inactiva y se podrá lanzar otra bala, la posición de la bala dependerá de la posición del avión.

Agregamos la imagen de una bala, a nuestra carpeta Content, luego creamos las variables necesarios:

Int32 PosBalaX = 0;
Int32 PosBalaY = 0;
Int32 velocidadBala = 10;
bool visible = false;

Inicializamos las variables:

PosBalaX = PosAvionX;

PosBalaY = PosAvionY;

Cargamos la imagen:

bala = Content.Load<Texture2D>(«bala»);

Cada vez que oprimamos la tecla espacio (Update) , se activa la variable visible:

            if (teclado.IsKeyDown(Keys.Space))
            {
                visible = true;
            }

Para que se esté actualizando la posición de la bala, creamos un método llamado disparar que va a aumentar la posición de la bala, solo si esta se encuentra activa, y va desactivarla cuando sobrepase la pantalla:

        private void Disparar()
        {
            if (visible == true)
            {
                if (PosBalaX <= (Window.ClientBounds.Width - bala.Width))
                {
                    PosBalaX += velocidadBala;
                }
                else
                {
                    PosBalaX = PosAvionX;
                    PosBalaY = PosAvionY;
                    visible = false;
                }
            }
            else
            {
                PosBalaX = PosAvionX;
                PosBalaY = PosAvionY;
            }
        }

La explicación del método es sencilla, si la variable visible es true, se mueve la bala solo si es menor al ancho de la pantalla, si no, se actualiza la posición de la bala a la posición del avión, también se actualiza la posición de la bala, si la variable visible es false.

Para que la función se llame, agregamos en el inicio del  método Update, el método Disparar:

protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
    this.Exit();
    teclado = Keyboard.GetState();
     Disparar();

Para finalizar, dibujamos la imagen:

spriteBatch.Begin();
spriteBatch.Draw(avion, new Rectangle(PosAvionX, PosAvionY, avion.Width, avion.Height), Color.White);
if (visible == true)
  {
   spriteBatch.Draw(bala, new Rectangle(PosBalaX + avion.Width, PosBalaY, bala.Width, bala.Height), Color.White);
   }
spriteBatch.End();

Ahora si probamos:

 

 Bueno, no es un juego perfecto, pero la intención es dar a entender como podemos crear algo tan fácil, pero que en otras plataformas tardariamos mucho más.

El código Fuente en Visual Studio 2008: Aquí.

13 pensamientos en “XNA – Inicio, Cargar, Mover y Disparar!

  1. Muy bueno lo que escribiste, me sirve bastante.

    Soy nuevo en esto de desarrollo de video juegos y me estoy iniciando con XNA, y la verdad que me gusta.

    Saludos

  2. muy buen tutorial, ya que tu sabes bien como es el manejo o programacion de un juego en xna, te pido de favor que me ayudes, el detalle es quiero que aparezca una especie de scroll en la pantalla del juego, si me puedes ayudar, te agradecería…

  3. Muy Buen tutorial, aunque ahora la pregunta es como hacer el efecto de estrellarse, o de matar al enemigo con las balas… podrias agregar eso?, soy novato en eso, y pues quisiera aprender…xD

    • En el método Disparar, evalua la variable PosX para que no sea menor que 0, si es menor que 0 significa que chocó con la parte de la izquierda, algo como esto:
      if (PosBalaX <= 0)
      {

      }

Deseas comentar o sugerir algo?