kalabaza.com.mx
Sitio de animación y desarrollo de video juegos

Fantasma

 

 


Sistema coordenado 2D

 

Es un conjunto de valores que se utilizan como referencia para localizar puntos en el espacio 2D.

 

 

SIstCoor

 

 

Esto ya lo sabemos y todos algunas vez hemos visto uno en la escuela, así que no ahondaré mas en el tema, sin embargo lo que nos interesa es lo siguiente:

 

En XNA cuando manejamos gráficos en 2D utilizamos también un sistema coordenado con ejes (X , Y) sin embargo el origen del mismo se encuentra en la esquina superior izquierda de la pantalla con el eje X a lo largo de la pantalla (positivo a la derecha) y el eje Y a lo alto de la pantalla (positivo hacia abajo) como se muestra en la imagen.

 

 

CoorPantalla

 

 

Por ejemplo, si queremos ubicar el punto (10,20) tendremos que avanzar 10 pixeles a la derecha y 20 pixeles hacia abajo. Las dimensiones de la pantalla dependerán de la resolución que se defina en el código.

 

 

Sprites y coordenadas

 

Las dimensiones de los sprites se miden utilizando el mismo sistema coordenado de la pantalla, tal que el ancho corresponde al eje de las X y el alto corresponde a las Y. Lo importante a destacar es que el origen de cualquier sprite esta en la esquina superior izquierda.

 

 

sprite

 

 

Esto es importante saberlo, primero por supuesto, para poder ubicar nuestros sprites pero también al momento de querer aplicar una rotación ya que será con respecto al origen y si queremos hacerlo rotar con respecto al centro del sprite tendremos que cambiar el origen al centro del mismo. De igual forma al escalar la imagen se expandirá a la derecha si se escala sobre el eje X y hace abajo si se escala en Y.

 

Ahora ya puedes consulta el post “Carga y animación de un sprite” , espero que quede más claro el concepto y sea más facil hacer la carga de los archivos.

 

Nos vemos en el siguiente post

 

 

Piroshi


Tags:

XNA

 

En esta ocasión vamos a ver como cargar imágenes en un proyecto de XNA además de crear una animación muy sencilla con las mismas. Puedes consultar la teoría previa en el post “Sistema coordenado 2D” donde encontrarás un par de conceptos útiles para entender mejor este post.

 

Lo primero que necesitamos es conseguir las imágenes que vamos a cargar, para lo cual si eres muy hábil para el dibujo puedes dibujar cada uno de los sprites tanto de los personajes, enemigos, fondos y demás para hacer tu juego completamente original. En realidad eso es lo que hay que hacer cuando ya se desarrolla un proyecto serio pero para nuestro caso y a modo de estudio vamos a ocupar sprites de juegos que ya existen y que fueron copy pasteados para nosotros. Existen varios sitios en Internet y varios juegos de donde podemos sacar las imágenes que nos hagan falta y ya depende de cada quien lo que quiera hacer. Para el ejemplo yo voy a ocupar sprites de Megaman por varias razones, primero, obvio, me gusta el juego y el personaje y segundo porque hay muchos sitios en Internet donde podemos descargar recursos de este juego. La imagen que utilicé para los sprites es la siguiente:

 

 

megaman sprites

 

 

La descargue del sitio sprites-resource que les recomiendo porque tiene una amplia variedad de sprites que podremos ocupar en nuestros proyectos.

 

Puedes hacer clic sobre ella para bajarla en tamaño completo; sin embargo existe un problema ya que no es solo bajar la imagen y cargarla en el proyecto. Para nuestro caso vamos a ocupar los sprites de megaman corriendo, así que habría que copiar cada uno de ellos y guardarlo en un archivo independiente en formato png, pero no te preocupes ya lo he
hecho para el ejemplo y puedes bajar todas las imágenes aquí.

 

Ya que tenemos las imágenes vamos a empezar con la programación. Lo primero será crear un proyecto nuevo (si no recuerdas como, puedes checar nuevamente la sección “Creacion un proyecto” . Para el ejemplo yo lo llamaré Ejemplo2D
pero puedes ocupar el nombre que quieras. También utilicé el nombre de Engine para la clase principal como hice el ejemplo de la sección “Análisis del código Inicial”.



Carga de Imágenes

 

Lo siguiente será cargar en nuestro proyecto las seis imágenes que vamos a
ocupar, para este necesitamos hacer clic derecho sobre la carpeta contets de nuestro explorador de soluciones y seleccionamos Agregar/Nueva carpeta.

 

 

Imagen1

 

 

Una vez que se ha creado damos clic derecho sobre la mism y seleccionanos Cambiar nombre ; el nombre que yo escribí pare el ejemplo es Sprites.

 

Ya que tenemos nuestra carpeta Sprite hacemos clic derecho sobre la misma y seleccionamos Agregar/Elemento existente.

 

 

Imagen2

 

 

En la ventana que aparece seleccionamos las imágenes y presionamos el botón Agregar.


Creación de una clase para nuestro personaje.

 

Podríamos hacer nuestra carga y animación de nuestro personaje en el mismo archivo Engine.cs pero para no romper con la estructura de la POO (Programación orientada a objetos) vamos a crear una clase que tendrá los métodos y atributos de nuestro personaje.

 

Para crear una clase nueva vamos a hacer lo siguiente: En nuestro explorador de soluciones hacemos clic derecho sobre el nombre de nuestro proyecto (En mi caso Ejemplo2D) y seleccionamos Agregar/Nuevo
elemento.

 

 

Imagen3

 

 

De la ventana que aparece seleccionamos una clase y escribimos el nombre AnimSprite.cs.

 

 

Imagen4

 

 

Yo escogí este nombre más genérico pensando en reutilizar esta clase en un futuro para otro fines pero
puedes llamarla personaje.cs o como quieras.

 

Código de la clase AnimSprite

 

Una vez que ya tenemos las imágenes en la carpeta lo siguiente es escribir el código para subir estas imágenes a un arreglo y así poderlas manipular posteriormente.

 

Lo primero que necesitamos es declarar un arreglo en donde se van a almacenar todos los sprites, asi que vamos a abrir la clase
AnimSprites.cs que acabamos de crear y dentro de la declaración de la clase escribimos la siguiente línea de código:

 

 
    public
Texture2D[] SpriteMov = new Texture2D[6];

 

Como pueden ver la clase que necesitamos para cargar las imagenes es Texture2D, si quieres ver la referencia de Microsoft de esta clase puedes consultarla aquí
.  

 

Vamos a utilzar un arreglo que en este caso tendrá una dimensión fija pero podemos hacer variable en modificaciones futuras. Como vamos a utilizar 6 sprites la dimensión de nuestro arreglo será también de 6.

 

Lo siguiente es definir un Vector que nos servirá para establecer la posición de nuestro personaje en pantalla, estoy utilizando el valor casi aleatorio de 200 en la coordenada X y 200 en Y pero puede ser cualquier valor dentro de nuestra resolución que ocupemos para el juego  que en nuestro caso es de 640×480. Para ello escribimos la siguiente línea de código.

 

      public Vector2 posicion = newVector2(200, 200);

 

Dado que vamos a hacer una animación por cuadros en necesario tener un contado que nos diga que frame se esta deplegando en este momento, para eso vamos a declarar una variable del tipo int que nos almecene esa información. La inicializamos a cero que es el indice de nuestro primer frame.

 

     public int  FrameActual = 0;

 

Ya que tenemos nuestros parametros los siguiente será los métodos. Primero necesitamos un método que nos dibuje en pantalla nuetro personaje; a este método lo llamaremos Draw() y el cuerpo del mismo es el
siguiente:

 

 
   public
 void Draw(SpriteBatch spriteBatch)
     {
       spriteBatch.Begin();
       spriteBatch.Draw(SpriteMov[FrameActual], posicion, Color.White);
       spriteBatch.End();
     }

 

El objetivo del método es simple, dibujar en pantalla el sprite que corresponde a nuestro frame actual y colocarlo en la posición actual, que para nuestro ejemplo será fija. Para lograr esto necesitamos el objeto spriteBatch que viene declarado por defecto al crear un proyecto nuevo y que como comenté en el post anterior, es el encargado de desplegar sprites en pantalla. Este objeto spriteBatch lo vamos a pasar como parámetro por el método Draw() de nuestra clase y lo que vamos a definir un bloque de Begin() End() en el que llamaremos al método Draw() del objeto spriteBatch. El bloque que comienza con el llamado al método Begin() lo que hace es básicamente prepar al dispositivo gráfico para desplegar sprites, este método tiene varias sobrecargas en las que podemos definir enrtre otras cosas la forma de renderes los sprites pero para nuestro caso no ocuparémos ningúna configuración adicional.

 

El método End() lo que hace es liberar el espacio ocupado por los sprites que se cargaron en spriteBatch y regresa al dispositivo gráfico al estado anterior que tenía antes de ser llamado por el método Begin().
El método Draw() recibe como parametros un objeto del tipo Texture2D, una objeto Vector2 para definir la posición y un objeto Color que se utiliza como máscara sobre el sprite que se esta dibujando.

 

Por último necesitamos declarar un método que controle el frame que se va a mostrar. Este método tendrá la siguiente estructura:

 

        public voidUpdateMov()
        {
            if (FrameActual < 5)
           {
                FrameActual = FrameActual + 1;
            }
            else
           {
                FrameActual = 0;
           }
        }

Lo que hace este método es básicamente incrementar la variable FrameActual  hasta que llega a su tope que en nuetro caso es 5. Una vez que llega a este valor se reinicia el contador a cero, lo
que nos regresa al primer frame de nuestra animación.

 

Programación de Engine.cs

 

Lo primero que vamos a hacer es declarar e instanciar un objeto de la clase que acabamos de crear, a este objeto lo llamaré Megaman

 

        AnimSprite Megaman = new AnimSprite();

 

Enseguida declaramos una variable con la que llevarémos el control del tiempo que pasa en la ejecución del programa.

 

        int  TiempoFlow;

 

Ahora, dentro del constructor de la clase (osea dentro Engine()) difinimos primeramente la resolucion de la pantalla, que como comenté antes será de 640×480. Para ello utilizaremos nuestro manejador gráfico y las variables  PreferredBackBufferWidth y PreferredBackBufferHeight.

 

            graphics.PreferredBackBufferWidth = 640;  
            graphics.PreferredBackBufferHeight = 480;

 

Opcionalmente pudes hacer que el juego se despliegue en pantalla completa en lugar de una ventada de 640×480. Para hacer esto tenemos que incluir la siguiente línea de código.

 

            graphics.IsFullScreen = true;

 

A continuación vamos a cargar cada una de las imagenes dentro de nuestro método LoadContent() escribiendo el siguiente código

 

          Megaman.SpriteMov[0] = Content.Load<Texture2D>(“Sprites/MM1″);

         Megaman.SpriteMov[1] = Content.Load<Texture2D>(“Sprites/MM2″);

         Megaman.SpriteMov[2] = Content.Load<Texture2D>(“Sprites/MM3″);

         Megaman.SpriteMov[3] = Content.Load<Texture2D>(“Sprites/MM4″);

         Megaman.SpriteMov[4] = Content.Load<Texture2D>(“Sprites/MM5″);

         Megaman.SpriteMov[5] = Content.Load<Texture2D>(“Sprites/MM6″);

 

Aprevechando que nuestro arreglo SpriteMov fue declarado public (por ahora) lo utilizaremos directamente para cargar cada imagen y esto lo haremos con el método Load del objeto Content. Lo que hace es cargar en cada elemento de nuestro arreglo las imagenes que tenemos en nuestra carpeta Content. El parámetro Texturu2D es para definir el tipo de dato que estamos cargando. La función soporta cualquiera de los siguientes tipos Model, Effect, SpriteFont, Texture, Texture2D, Texture3D y TextureCube aunque no creo que los ocupemos todos en este tutorial o por lo menos no por un buen rato.

 

Dentro de la función Update() básicamente vamos a hacer dos cosas una es llamar a la funcion UpdateMov() de nuestro objeto megaman y la otra es modificar la condición de salida del juego.

Para hacer lo primero bastaría con escribir Megaman.UpdateMov(); sin embargo la animación sería muy rápida y no la podríamos apreciar, por esta razón fue que declaramos la variable TiempoFlow y la vamos a ocupar de la siguiente forma.

 

       TiempoFlow = TiempoFlow + gameTime.ElapsedGameTime.Milliseconds;

 

         if (TiempoFlow > 50)
         {
             TiempoFlow = 0;
             Megaman.UpdateMov();
         }

 

ElapsedGameTime es una propiedad de la clase gameTime que nos regresa el tiempo que ha pasado desde la última vez que se invocó al método Update(); seleccionamos Miliseconds para que el valor devuelto sea en milisegundos (obvio).

 

Cada que entramos al método Update() la variable TiempoFlow se incrementa; este incremento será los n milisegundos que transcurrieron desde la última vez (alrededor de 16 milisegundos) y al alcanzar un valor mayor a 50 actualizará nuestra animación y nos mostrará el siguiente frame. Por otro lado regresaramos nuestro contador a cero para empezar de nuevo.

Lo siguiente que vamos a hacer es modificar la condición de salida del juego ya que originalmete se cumple presonar el botón Back de nuestro control pero nosotros estamos probando el juego en el teclado asi modificamos el código para que quede de la siguiente forma :

 

            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Escape))
                this.Exit();

 

De esta forma cada que entre al método Update() verificará si se ha presionado la tecla Esc y si es así terminará el programa. Para el siguiente post hablaré mas sobre la función GetState() y sus usos.

 

Por último vamos a modficar el método Draw(). Para esto lo único que vamos a hacer es llamar al método Draw() de nuestro objeto megaman y pasarle como parámetro el spriteBatch como ya expliqué antes, pero antes de llamarlo tenemos que limpiar la pantalla y dejar un color blanco de fondo porque nuestros sprites tiene fondo blanco.

 

             GraphicsDevice.Clear(Color.White);
             Megaman.Draw(spriteBatch);

 

Listo, si todo salió bien y ejecutas el programa deberías ver algo así, claro que en movimiento:

 

Imagen5

 

Si lo deseas puedes bajar el código fuente completo de aqui.

 

Así de simple es cargar sprites a un programa en XNA. Cabe señalar que parte del código es repetitivo y rompe con algunas reglas de la POO pero me pareció que de esta forma es más fácil de entender. En el siguiente post mejoraré el código ya que espero que haya quedado claro en este post. Si hay alguna duda no dejes de postearla en la parte de abajo y no olvides tampoco
tus comentarios. Nos vemos en el siguiente post.

 

Piroshi


Tags: ,

—–



Powered by Wordpress
Theme © 2005 - 2009 FrederikM.de
BlueMod is a modification of the blueblog_DE Theme by Oliver Wunder