Tutorial de XNA: Texturas 2D

Antes de comenzar con este tutorial, primero aclararemos la ‘tarea’ del último tutorial.
1. ¿Cómo logramos que el texto se mueva en más de una dirección?
R. Habiamos dicho que con el código…

KeyboardState teclado = Keyboard.GetState();
 
            if (teclado.IsKeyDown(Keys.W))
            {
                textVector.Y--;
            }

Se movia hacia arriba el texto, porque el eje Y, negativo, es hacia arriba. Para moverlo en otras direcciones, pues…

if (teclado.IsKeyDown(Keys.W))
            {
                textVector.Y--;
            }
if (teclado.IsKeyDown(Keys.S))
            {
                textVector.Y++;
            }
if (teclado.IsKeyDown(Keys.D))
            {
                textVector.X++;
            }
if (teclado.IsKeyDown(Keys.A))
            {
                textVector.X--;
            }

Y listo!

2. ¿Cómo evitamos que salga de la pantalla?
R. Esta es una solución muy fácil, pero creo que aplica más con el ejemplo de este tutorial, asi que, sin preambulos, veamos como resolverlo en este tutorial… pero de paso, utilizando imágenes!

Bien, con eso fuera del camino, comenzamos.
Un sprite en un juego, es básicamente una imágen 2D. Pongamos un ejemplo bastante básico: Una paleta y una pelota de pong.

Arte de videojuegos
Diseño gráfico avanzado en proceso

En paint creamos un simple rectangulo de 20 x 40 pixeles (20 de ancho, 40 de alto) y le damos un color cualquiera. Lo guardamos como “paleta.png”. La razón del por qué usamos el formato png es muy simple: con este color podemos agregar colores alpha luego… pero esto se verá en otra ocasión.
De paso creamos una pelota también (de 10×10 por ejemplo) pero no veremos como moverla aún, aunque estan bienvenidos de intentarlo.

Por ahora agregamos nuestra imágen. ¿Cómo lo hacemos? Es más fácil de lo que creen, y de hecho ya saben como hacerlo.

Primero, para poder tener la imágen cargada, la ponemos en un objeto de tipo Texture2D.

Texture2D paleta;

La declaramos junto a los demás objetos que tenemos hasta ahora. Acto seguido, necesitamos darle un valor. Para esto se requiere primero de cargar la imágen a nuestra solución. Explicaré como se agrega una imágen a nuestra solución, pero a partir de aquí asumiré que ya lo leyeron, y saben como agregar multimedia a la solución, asi que, atención: ¡no repetiré el proceso!

Menus y más menus

Click derecho en nuestro contenido, agregar, agregar existente, y buscamos nuestra imágen. Fácil, ¿no? También pueden simplemente arrastrar la imágen hacia el área del proyecto de “contenido”.

Ahora lo que necesitamos es cargarlo al objeto. Para esto se sigue el mismo proceso que usamos para cargar el font. En nuestro método LoadContent() escribimos:

paleta = Content.Load<Texture2D>("paleta");

Solo recuerden que “paleta” es el nombre de la imágen, y que no se debe de escribir la extensión .png. Si quieren ser más organizados, pueden poner las imágenes y archivos en carpetas, solo recuerden que si hay carpetas (por ejemplo, una carpeta que diga Sprites y ahi ponemos nuestras imágenes 2D) entonces se escribira (“Sprites/paleta”);

¡Bien! Ahora que tenemos nuestra imágen en el proyecto, es hora de colocarlo en la pantalla. Para lograr esto… ¡necesitaremos un nuevo objeto! Sin embargo, a diferencia del texto, necesitaremos algo un poco más… especializado. Damos una bienvenida al objeto Rectangle, el cual nos permite colocar la imágen dentro de dicho rectangulo y al mover el rectángulo, movemos la imágen. Colocamos con el resto de nuestros objetos:

Rectangle paletaPos;

…y la inicializamos en el metodo Initialize()

paletaPos = new Rectangle(0,0,20,40);

Esto quiere decir que, queremos un rectangulo en la posicion 0,0… y que mida 20 de ancho, por 40 de alto. Ojo, no son cuatro posiciones X,Y,X2,Y2. Es la posicion más alta a la izquierda, X,Y, y que tan ancho y alto a partir de dicho punto será. Recordamos que nuestra paleta media 20 x 40 asi que es lo que colocamos en la declaración del objeto.

Finalmente para dibujarlo en la pantalla, reemplazamos nuestro método drawstring, en el método Draw() por:

protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here

            spriteBatch.Begin();
            spriteBatch.Draw(paleta, paletaPos, Color.White);
            spriteBatch.End();

            base.Draw(gameTime);
        }

Nada cambio, excepto que ahora tenemos el método spriteBatch.Draw(); para dibujar imágenes, y una de las formas para usarlo es dandole la imágen, luego el rectangulo de la posición, y al final el color con el que dibujaremos. El color blanco significa que no le pinte nada por encima, y que active los colores alpha, si es que hay, en la imágen. ¡Ejecutamos el código y probamos!

Eso es todo por ahora. Les dejo el código ejemplo, vean como incluso agregue un poco de movimiento a la paleta. Pero daniel… ¡no hemos resuelto que la imágen no se salga de la pantalla! Paso a paso pequeños saltamontes, primero tienen que entender como funciona el alto y ancho en rectangulos para poder mantener una imágen dentro de la pantalla.


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;

namespace Tutorials
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SpriteFont miFont;
        Texture2D paleta;
        Rectangle paletaPos;

        Vector2 textVector = Vector2.Zero;

        string textoFinal = "Default";
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            paletaPos = new Rectangle(0, 0, 20, 40);

            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            miFont = Content.Load<SpriteFont>("miFont");
            paleta = Content.Load<Texture2D>("paleta1");
        }

        
        protected override void UnloadContent()
        {

        }


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

            if (teclado.IsKeyDown(Keys.W))
            {
                paletaPos.Y--;
            }
            if (teclado.IsKeyDown(Keys.S))
            {
                paletaPos.Y++;
            }
            if (teclado.IsKeyDown(Keys.A))
            {
                paletaPos.X--;
            }
            if (teclado.IsKeyDown(Keys.D))
            {
                paletaPos.X++;
            }
            

            // TODO: Add your update logic here

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here

            spriteBatch.Begin();
            spriteBatch.Draw(paleta, paletaPos, Color.White);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

Leave a Reply