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

XNA

 

 

Bienvenidos a este nuevo post en el que como dice el título vamos a programar el scroll del fondo para nuestro juego en 2D que hemos estando programando Si quieres conocer un poco sobre algunos tipos de fondos que se pueden programar en un juego 2D, puedes consultar el post “Background Images” antes de continuar.


Los puntos que vamos a ver en este post son los siguientes :

  • Cargar imágenes de fondo
  • Crear un Arreglo de objetos para los fondos
  • Programación del movimiento del scroll
  • Aplicación de este método

Primero voy a explicar lo que vamos a hacer.

Hasta el momento lo que tenemos es a nuestro personaje que se puede desplazar de derecha a izquierda en un escenario de fondo fijo. Si el personaje se desplaza fuera de los límites de la pantalla, simplemente sale de nuestro campo de visión y hay que avanzar en la dirección opuesta para volverlo a ver. Lo que queremos es básicamente un escenario más grande y que nuestra cámara imaginaria siga el movimiento de nuestro personaje. Para lograr esto vamos a programar un fondo con avance por movimiento del personaje. Podríamos cargar una imagen grande y desplazarla conforme el personaje va avanzando como se ve en la siguiente imagen.

 

 

FondoLargo1

El problema con esta solución es que tendríamos que cargar una imagen muy grande y si hay partes del nivel en las que el personaje se desplaza hacia arriba o abajo tendríamos partes de la imagen que irían vacías y se desperdiciaría el espacio. Es cierto que si estamos programando un juego en 2D en XNA nos debería importar un cacahuate desperdiciar memoria y más aún que estamos empezando con un programa tan sencillo podríamos cargar imágenes muy grandes sin preocuparnos por el desempeño, sin embargo creo que siempre es bueno tener en mente la optimización de recursos, principalmente porque las técnicas que aprendamos aquí las podemos llevar a otros entornos de desarrollo como dispositivos móviles en los que el uso de memoria y procesador sigue siendo algo muy importante, por lo que se recurre algunas veces al desarrollo de juegos basados en tiles para ahorrar recursos. Además si ocupamos tiles para el fondo podemos ahorrarnos también tiempo de diseño; bueno en caso de que empieces a desarrollar tus propios fondos.

Por estas razones es que utilizaré un método en que utilizo tres fondos que se irán mostrando uno tras otro conforme el personaje va avanzando de la siguiente manera:


FondoLargo2

 

Cuando el personaje avance a la derecha y llegue a la coordenada X = 540 empezaremos a desplazar  el fondo a la izquierda y para nuestro ejemplo también si el personaje avanza a la izquierda y alcanza la coordenada X=100 se desplazará a la derecha. Por otro lado, la forma en la que se irán mostrando los fondos será cíclico, es decir en el siguiente orden: uno, dos, tres, uno, dos, tres, uno…. etc. Si el avance es hacia la izquierda será de igual forma : tres ,dos , uno, tres, dos, uno … etc.

 

 

Cargar imágenes de fondo

 

Lo primero que vamos a hacer es cargar las imágenes de fondo a nuestro proyecto de la misma forma en que lo hicimos en el post “Carga y animación de sprites”; Es importante que cargues las tres porque Fondo1.png, aunque tiene el mismo nombre fue modificada.
Las tres imágenes de fondo las puedes bajar de aquí

 

 

Crear un Arreglo de objetos para los fondos

 

Lo siguiente que vamos a hacer es utilizar nuestra clase AnimSprite para los fondos de imagen. La razón de este cambio es porque ahora necesitamos modificar la posición de los mismo y con la estructura actual tendríamos que declara un vector por cada fondo, cosa que rompería con nuestra estructura orientada a objetos que queremos mantener pues estaríamos utilizando un objeto y sus propiedades como entidades diferentes. Talvez la solución más adecuada sería crear una nueva clase Fondos o una clase Sprites de la que la heredera sus funciones AnimSprites pero creo que si hacemos este cambio será más adelante cuando empecemos a agregar otro tipo de elementos al juego.

 

Para crear los objetos vamos a abrir nuestra clase Engine.cs y primero vamos a sustituir la línea

 

         privateTexture2DFondo1;

 

por esta otra:

 

        AnimSprite[] Fondos = newAnimSprite[3];

 

para declarar nuestro arreglo que utilizaremos para los tres fondos. Por otro lado tenemos que modificar el código que utlilizamos para cargar las imagenes para hacerlo de una forma parecida a la que cargamos los sprites de Megaman. El código lo vamos a agregar dentro de nuestro método LoadContent() para sustituir al código que utilizábamos anteriormente y quedará así:

           
for (int i = 1; i <= 3; i++)
           {
                int Px = (i – 1) * 730;
                Fondos[i - 1] = new AnimSprite(Px, 0,0, new Vector2(0,0));
                Fondos[i - 1].CargaImagen(Content.Load<Texture2D>(“Sprites/Fondo” + i));
           }

 

Lo que estamos haciendo aquí, es iterar tres veces para cargar los tres fondos y como hicimos con los sprites de Megaman, aprovechamos el número al final del nombre de la imagen para no tener que escribir el código tres veces.
La variable temporal Px la ocupamos para determinar la posición X inicial de los fondos, aunque esta posición solo nos interesa para las primeras dos imágenes, como veremos más adelante. La forma en que determinamos la posición es utilizar la variable i del ciclo for para multiplicarlo por 730, que es el ancho de cada imagen de fondo; Es importante que las tres imágenes tengan las mismas dimensiones y si cargan otras imágenes es importante modificar este valor por el ancho de las imágenes a cargar, por otro lado, si deciden cargar imágenes de diferentes dimensiones este valor deberá ser variable.
Una vez que determinamos la posición X por cada fondo, instanciamos cada objeto con el constructor que creamos la vez anterior. Ya con el objeto creado utilizamos el método CargaImagen() para copiar cada imagen en los objetos.
Finalmente en este paso vamos a modificar en el método Draw() de nuestra clase Engine.cs para dibujar el fondo utilizando el método Draw() de nuestros objetos pero para hacer esto tengo que explicar varias cosas antes.
Primero, como ya explique, vamos a ocupar tres imágenes de fondo que se irán desplazando en la pantalla en sentido contrario al desplazamiento de nuestro personaje. Las dimensiones de cada imagen son 730×480 y conforme la primer imagen se va desplazando, se va mostrando la siguiente y una vez que esta a alcanzado el extremo opuesto de la pantalla, ocupará toda la pantalla hasta que se desplace lo suficiente para dar espacio a la siguiente. Lo que quiero decir es que en el proceso siempre se mostrarán una o dos imágenes en pantalla pero nunca tres. (Para que esto último ocurriera se necesitaría que el ancho de las imágenes de fondo fuera menor al ancho de la pantalla o para nuestro caso 480 pixeles ya que de esta forma habría un punto en el que se mostrarán tres imágenes en pantalla).

 

 

TresFondos

 

 

Por consiguiente vamos a estar manejando el movimiento de dos imágenes a la vez y por lo tanto primero vamos a declarar dos variables que utilizaremos para definir los dos fondos que se mostrarán. Estas dos variables se declararan dentro de nuestra clase Engine.cs y tendrán el valor inicial 0 y 1 que serán los dos primeros fondo que empezaremos a manejar.

 

        int FIndex1 = 0, FIndex2 = 1;

 

 

Nota: Existe una forma de programar el scroll de la pantalla en el que se cargan todos los fondos a la vez y va modificando la coordenada X de cada uno de ellos. Esta forma es más fácil de programar pero implica haber cargado todos los fondos en memoria, que es algo que como comente al principio quiero evitar.

 

 

Ya que tenemos las dos variables declaradas, ya podemos escribir las siguientes líneas dentro del código Draw().

 

 

            Fondos[FIndex1].Draw(spriteBatch);
            Fondos[FIndex2].Draw(spriteBatch);

 

 

Programación del movimiento del scroll

 

Lo siguiente que vamos a hacer es modificar el método Update() que es donde se llevará a cabo el cambio de posición de nuestros dos fondos.  Empezaremos por limitar el movimiento de nuestro personaje; Anteriormente incrementábamos 10 pixeles la posición del personaje si avanzaba a la derecha o disminuimos 10 si avanzaba a la izquierda. Lo que haremos ahora es permitir este mismo movimiento solo si se encuentra dentro del área permitida que es entre 100 y 540 que es 100 pixeles más del borde izquierda y 100 pixeles menos del borde derecho.

 

 

limites_Pant

 

 

Para hacer esto vamos a escribir un if a nuestro incremento de la posición al avanzar a la derecha de la siguiente manera

 

                 if (Megaman.XPos < 540)
                      Megaman.XPos += 10;

 

de igual forma limitamos el avance a la izquierda de la siguiente manera:

 

                  if (Megaman.XPos > 100)
                      Megaman.XPos -= 10;

 

Con esto limitamos el avance del personaje pero no la animación. Lo que vamos a hacer ahora es incluir el código que desplaza los fondos para crear la ilusión de que el personaje sigue avanzando. Para lograr esto incluimos código debajo del if que agregamos para el avance a la derecha.

 

                  else
                 {
                      Fondos[FIndex1].XPos -= 10;
                      Fondos[FIndex2].XPos -= 10;

                        if (Fondos[FIndex2].XPos == 0)
                       {
                         FIndex1 = FIndex2;
                         Fondos[FIndex1].XPos = 0;

                           if(FIndex2 < 2)
                              FIndex2 += 1;
                           else
                             FIndex2 = 0;

                         Fondos[FIndex2].XPos = 730;
                     }
                 }

 

Lo que hacemos primero es reducir 10 pixeles a la posición en X de los dos fondos que estamos dibujando a la vez; Originalmente son los fondos 0 y 1.
Ya que reducimos los valores, verificamos que el segundo fondo (FIndex2) no haya alcanzado el borde izquierdo de la pantalla. De ser así necesitamos tener preparado el siguiente fondo del lado derecho y además vamos a cambiar los índices de los fondos de tal forma que el índice FIndex1 siempre esté apuntando al fondo de la izquierda y el índice FIndex2 siempre apunte al índice más a la derecha, como se muestra en la siguiente imagen:

 

 

CambioIndex

 

 

Lo que hacemos para lograr esto es pasar el valor de FIndex2 a FIndex1 , este movimiento lo podemos ver como si estuviéramos utilizando apuntadores y queremos que FIndex1 apunte ahora a la imagen a la que apuntaba FIndex2. Ya que  hicimos este cambio ahora vamos a mover el fondo a la posición 0 y con esto tendríamos a los dos Fondos con la misma imagen y en la misma posición. Los siguiente es cambiar primero la imagen que se desplazará del lado izquierdo. Para determinar esto lo que vamos a hacer es incrementar en 1 el valor de FIndex2 si el valor previo es menor a 2 (que es el indice de nuestro último fondo ) o le pasamos el valor de 0 si ya estábamos mostrando el último fondo. Por último vamos a desplazar este fondo a la posición X=730 que es el ancho de todas nuestras imágenes.
De igual forma para el desplazamiento a la izquierda escribimos este código.

 

                  else
                 {
                      if (Fondos[FIndex1].XPos == 0)
                     {
                          FIndex2 = FIndex1;
                          Fondos[FIndex2].XPos = 0;

                            if (FIndex1 > 0)
                              FIndex1 -= 1;
                           else
                              FIndex1 = 2;

                          Fondos[FIndex1].XPos = -730;
                     }

                      Fondos[FIndex1].XPos += 10;
                      Fondos[FIndex2].XPos += 10;
                 }

 

Para el desplazamiento a la izquierda lo que tenemos que hacer es incrementar la posición de los fondos en lugar de reducirlo. Sin embargo como podemos observar, este incremento de la posición de las variables no esta al principio del bloque sino al final, esto es debido a que si al iniciar el programa decidimos movernos a la izquierda primero incrementaría la posición en X del fondo y después verificaría si es igual a cero pero ya no sería 0 sino 10. Por otro lado, cuando el primer fondo alcanza la posición 0 lo vamos a desplazar a la izquierda a la posición -730 y el fondo al que apunta FIndex2 estará en pantalla. El código completo de este ejemplo lo puedes descargar aquí

 

 

Aplicación de este método

 

La razón principal para utilizar este método para el scroll es, como comenté antes, la facilidad para reutilizar los fragmentos de fondo y crear un fondo más grande de varias combinaciones. Para lograr esto lo que podemos hacer es utilizar un arreglo de índices en el que podamos almacenar que indice va a continuación del otro y seguir utilizando nuestras variables FIndex1 y FIndex2 para aumentar al fondo que se va a mostrando como se muestra en el siguiente esquema:

 

 

FondosArreglo

 

 

Como podemos ver utilizamos los mismos tres fondos y las mismas dos variables pero como paso intermedio tenemos el arreglo que va almacenar los indices de los fondos. Este arreglo puede ser tan grande como queramos y al contrario de nuestro ejemplo puede tener un límite en el que impidamos el avance del personaje. La programación de esta aplicación la dejo de tarea a quién quiera aplicarla para seguir en el siguiente post con la segunda parte de scrolls para fondos.

Como siempre espero sus comentarios y sugerencias y espero que haya sido de su agrado este post. Nos vemos en el siguiente.

 

 

Piroshi.

 

 

 


Tags: ,

Fantasma

 

 

En esta ocasión voy a explicar un poco sobre backgrounds en los juegos 2D principalmente para conocer algunas de las posibilidades que se tienen al desarrollar un juego de este tipo.

 

Como sabemos el “Background image”es la imagen o las imágenes de fondo que se ocupan en juegos 2D y algunos 3D, según el tipo de juego, la consola que se utilice y la creatividad del equipo de desarrollo pueden existir varios tipos de Backgrouds. A continuación haré una clasificación en base a las características más importantes.

 

 

Fondos Fijos

 

Podemos decir que los juegos más sencillos ocupan imágenes fijas como fondos de pantalla. En un principio, se ocupaban mucho los tiles para ahorrar recursos, ya que en lugar de guardar una imagen de (640×480) se podía llenar toda la pantalla  con unos 10  o menos tiles de (32 x24) repetidos varias veces.

 

 

super_bomberman

Bonberman

 

 

En la actualidad existen todavía juegos que por la naturaleza de los mismo utilizan imágenes fijas, por no requerir más que una pantalla para su función.

 

 

Super Puzzle Fighter II Turbo HD Remix

Super Puzzle Fighter II Turbo HD Remix

 


Fondo Fijos de avance por pantalla

 

Una variante a los fondos fijos se observa en juegos como el primer “The Legend of Zelda” en el que en toda la pantalla se arma una parte de un mapa y no cambia ni se mueve hasta alcanzar alguno de los cuatro bordes de la pantalla; en ese momento se genera una animación en el que se desplaza el fondo y se carga una nueva parte del mapa. Este avance por pantallas ahorra recursos porque una vez cargado un escenario los cálculos se concentran solamente en los enemigos y el personaje.

 

 

legend_of_zelda_nes-1

The legend of Zelda

 

 

Avance del fondo por movimiento del personaje.

 

La evolución de los fondos fijos de avance por pantalla se vio al contar con más memoria y fue posible cargar imágenes más grandes. Con esta facilidad fue que en lugar de cargar un fragmente de un mapa del tamaño de la pantalla se podían cargar fracciones más grandes que se desplazaban al llegar a un punto cercano de unos de los bordes (uno, dos, o los cuatro bordes, según el tipo de juego) y una vez que se alcanza el final de esta sección se pasa a otro parte del escenario utilizando un efecto de fade, un desplazamiento de la pantalla o algún tipo de animación que mostrara el cambio de escenario. Ejemplos de este tipo de juegos tenemos de sobra.

 

 

megaman6nes

Megaman 6

 

 

Profundidad en el fondo.

 

El siguiente paso en la evolución fue agregar varías capas de fondo así como elementos sobre el plano principal para generar un afecto de profundidad en los niveles. Este tipo de técnica se ocupa actualmente en la mayoría de juegos 2D que no recurren a elementos tridimensionales.

 

 

a boy and his blob

A boy and his blob

 

 

Fondo 2D con personajes 3D

 

Una técnica que se empezó a ocupar al iniciar el salto a los juegos en 3D fue utilizar imágenes 2D prerendereadas con personajes y algunos elementos en 3D esto por no contar con la tecnología suficiente para crear los escenarios completos en tiempo real. Como ejemplo de estos juegos tenemos los primeros Resident evil y o final fantasy VII y VIII que aunque incluían partes completamente en 3D también recurrían al uso de imágenes prerensereadas.

 

 

resident evil 1

Resident evil

 

PSX_FF7

Final Fantasy 7

 

 

Actualmente podemos encontrar todavía juegos que utilizan una mezcla entre 2D y 3D. El genero que más recurre a esta practica es el de los puzzles que muchas veces se desarrollan en una misma pantalla y aunque pueden contener elementos en 3D el fondo puede ser una imagen estática.

 

 

butterfly_escape

Butterfly escape

 

 

Existen aún más técnicas para generar  los Backgronds de los juegos en 2D como por ejemplo los juegos de carreras o los juegos de naves. Todos finalmente ocupan imágenes que son dibujadas en pantalla utilizando varias técnicas para lograr diferentes efectos. En este post solo comenté los que me parecen los más destacados para mostrar tanto la evolución como las posibilidades con las que contamos al desarrollar juegos en 2D Ahora ya puedes consultar el post Fondos con scroll en el que explico una téctica para agregar scroll a nuestros juegos en 3D. Espero que les haya gustado este post, nos vemos próximamente

 

 

Piroshi

 


Tags:

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