El trabajo propuesto

El fondo de la pantalla, en vez de ser negro, deberá estar formado por "casillas" que representen fragmentos de pared vertical, pared horizontal, escaleras y pasillos, imitando la apariencia del juego original. Se debe emplear un "array" de dos dimensiones.

Además, los murciélagos no deberán estar exactamente uno sobre el otro, sino situados al azar.

Como mejora opcional, las imágenes no deberán tener fondo negro, sino ser transparentes.

Forma de conseguirlo

En muchos juegos de plataformas, wel fondo está formado por casillas repetitivas de un cierto tamaño. En el caso de Death Pit, cada pantalla procede de una cuadrícula de 7 filas por 7 columnas:

Cuadricula de tiles

Este mapa podría ser un array de dos dimensiones, en el que cada una de esas casillas repetitivas se represente con un número. Por ejemplo, un 1 podría ser suelo horizontal, un 2 podría ser un suelo del que cae ácido, un 3 podría ser una pared vertical, un 4 una escalera y un 0 espacio en blanco, para un resultado como éste:

int[,] mapa = {
  {1,2,1,1,1,2,1},
  {0,0,0,0,0,0,0},
  {1,1,3,4,3,1,1},
  {0,0,3,4,3,0,0},
  {1,4,3,4,3,4,3},
  {0,4,3,4,3,4,3},
  {1,1,3,4,3,4,3}
};

A la hora de dibujar el mapa, comprobaremos cual es cada una de las posiciones del mapa y dibujaremos la imagen correspondiente:

 
Hardware.BorrarPantallaOculta(0,0,0);
 
// Dibujo el fondo de la pantalla
for (i=0; i<filasPantalla; i++)
  for (j=0; j<columnasPantalla; j++)
    switch (mapa[i,j]) {
 
      case 1:
          imagenFondoHoriz.MoverA( (short) (j*70) , (short) (i*50));
          imagenFondoHoriz.DibujarOculta();
          break;
 
      case 2:
          imagenFondoHorizAcido.MoverA( (short) (j*70) , (short) (i*50));
          imagenFondoHorizAcido.DibujarOculta();
          break;
 
      (...)
 

Para que los murciélagos se muevan de forma independiente, ya no nos bastará con una única variable "incremento", sino que necesitaremos un array de incrementos, de forma que unos puedan estar moviéndose a la derecha (incremento = +1) mientras otros vayan a la izquierda (incremento = -1):

 
for (i=0; i<6; i++) 
{
  xMurcielagos[i] += incrXMurcielagos[i];
 
  // Los murcielagos rebotan en los lados
  if ( (xMurcielagos[i] >= maxX) 
       ||  (xMurcielagos[i] <= minX) )
    incrXMurcielagos[i] = (short) -incrXMurcielagos[i];
}
 

Y para que la X de cada murciélago comience teniendo un valor al azar, deberíamos usar Random, de la siguiente forma (necesita "using System" al principio del programa):

 
Random numAleatorio;        
numAleatorio = new Random( DateTime.Now.Millisecond );
for (i=0; i<6; i++) {         
  xMurcielagos[i] = (short) numAleatorio.Next(0,maxX);
  incrXMurcielagos[i] = 1;
}
 

Lo de las imágenes transparentes no es realmente una tarea de programación. Se puede hacer desde The GIMP, por ejemplo. Como nuestras imágenes están en formato PNG, que permite transparencia, los pasos serían: abrir la imagen, añadir canal alfa (desde el panel de capas), seleccionar con la varita mágica la zona negra que rodea la imagen, pulsar la tecla Supr para borrarla, y finalmente guardarlos cambios.

En esta entrega, la apariencia sería:

Apariencia de la version 0.06

Y el fuente completo quedaría así:

/** 
 *   Juego: Logica de juego
 *  
 *   @see Hardware
 *   @author 1-DAI IES San Vicente 2009/10
 */
 
/* --------------------------------------------------         
   Parte de Death Pit - Remake
   Versiones hasta la fecha:
 
   Num.   Fecha       Por / Cambios
   ---------------------------------------------------
   0.01  08-Sep-2009  Nacho Cabanes
                      Version inicial: muestra una imagen
   0.02  07-Oct-2009  Nacho Cabanes
                      Mueve el personaje hacia la derecha
                        hasta llegar al margen
   0.03  13-Oct-2009  Nacho Cabanes
                      El personaje se mueve con flechas
                      Un primer enemigo que se mueve a la vez
   0.04  16-Oct-2009  Nacho Cabanes
                      Primera pantalla de presentacion
                      El primer enemigo rebota en los lados
                      Un segundo enemigo nos persigue
   0.05  20-Oct-2009  Nacho Cabanes
                      Array de enemigos (murcielagos)
                       que rebotan en los lados
   0.06  28-Oct-2009  Nacho Cabanes
                      Array bidimensional para fondo de pantalla
                      Murcielagos con X aleatoria
 
 ---------------------------------------------------- */
 
 using System; // Para numeros aleatorios: System.Random
 
public class Juego
{
 
    private static void Main()
    {
        // Variables que usaremos: una imagen y un tipo de letra
        ElemGrafico imagenPersonaje,
          imagenEnemigo2, presentacion;
        ElemGrafico[] imagenesMurcielagos;   
        ElemGrafico imagenFondoHoriz,imagenFondoHorizAcido,
          imagenFondoVert, imagenEscalera;
        Fuente fuente18;
        int i, j;
 
        short x = 100, xEnemigo2 = 50;
        short[] xMurcielagos;
        short[] incrXMurcielagos;
        short y = 300, yEnemigo2 = 200;
        short incremento = 1;
        int minX = 0, maxX = 730;
 
        int filasPantalla = 7;
        int columnasPantalla = 7;
 
        int[,] mapa = {
          {1,2,1,1,1,2,1},
          {0,0,0,0,0,0,0},
          {1,1,3,4,3,1,1},
          {0,0,3,4,3,0,0},
          {1,4,1,4,3,4,3},
          {0,4,3,4,3,4,3},
          {1,1,3,4,3,4,3}
        };
 
        imagenesMurcielagos = new ElemGrafico[6];
        xMurcielagos = new short[6];
        incrXMurcielagos = new short[6];
 
        // Inicializo modo grafico 800x600 puntos, 24 bits de color
        Hardware.Inicializar(800, 600, 24);
 
        // Cargo imagenes y tipos de letra
        imagenPersonaje = new ElemGrafico("imagenes/personaje.png");
 
        for (i=0; i<6; i++)
          imagenesMurcielagos[i] = new ElemGrafico("imagenes/murcielago.png");
 
        // La X de los murciélagos será al azar
        Random numAleatorio;        
        numAleatorio = new Random( DateTime.Now.Millisecond );
        for (i=0; i<6; i++) {         
          xMurcielagos[i] = (short) numAleatorio.Next(0,maxX);
          incrXMurcielagos[i] = 1;
        }
 
        imagenEnemigo2 = new ElemGrafico("imagenes/escorpion.png");
        imagenFondoHoriz = new ElemGrafico("imagenes/fondo1.png");
        imagenFondoHorizAcido = new ElemGrafico("imagenes/fondo2.png");
        imagenFondoVert = new ElemGrafico("imagenes/fondo3.png");
        imagenEscalera = new ElemGrafico("imagenes/escalera.png");
 
 
        fuente18 = new Fuente("FreeSansBold.ttf", 18);
        presentacion = new ElemGrafico("imagenes/present.png");
 
        //dibujo la presentacion
        presentacion.DibujarOculta();
 
        // Finalmente, muestro en pantalla
        Hardware.VisualizarOculta();  
 
        //hasta que se pulse espacio
        do {
 
        } while (! Hardware.TeclaPulsada(Hardware.TECLA_ESP) );
 
        //borro la presentacion
        Hardware.BorrarPantallaOculta(0,0,0);
 
        // Y espero a que se pulse ESC
        do {
 
          Hardware.BorrarPantallaOculta(0,0,0);
 
          // Dibujo el fondo de la pantalla
          for (i=0; i<filasPantalla; i++)
            for (j=0; j<columnasPantalla; j++)
              switch (mapa[i,j]) {
 
                case 0:  // Espacio en blanco, no dibujo nada
                    break;
 
                case 1:
                    imagenFondoHoriz.MoverA( (short) (j*70) , (short) (i*50));
                    imagenFondoHoriz.DibujarOculta();
                    break;
 
                case 2:
                    imagenFondoHorizAcido.MoverA( (short) (j*70) , (short) (i*50));
                    imagenFondoHorizAcido.DibujarOculta();
                    break;
 
                case 3:
                    imagenFondoVert.MoverA( (short) (j*70) , (short) (i*50));
                    imagenFondoVert.DibujarOculta();
                    break;
 
                case 4:
                    imagenEscalera.MoverA( (short) (j*70) , (short) (i*50));
                    imagenEscalera.DibujarOculta();
                    break;
 
              }
 
          // Dibujo el personaje, el enemigo y un texto en la pantalla oculta
          imagenPersonaje.MoverA( x ,y);
          imagenPersonaje.DibujarOculta();
 
          for (i=0; i<6; i++)
          {
            imagenesMurcielagos[i].MoverA( 
              xMurcielagos[i] , (short) (100+i*70) );
            imagenesMurcielagos[i].DibujarOculta();
          }
 
          imagenEnemigo2.MoverA( xEnemigo2 ,yEnemigo2);
          imagenEnemigo2.DibujarOculta();
 
          Hardware.EscribirTextoOculta(
                "Pulsa ESC para salir",
                300, 500, 0xAA, 0xAA, 0xAA, fuente18);
 
          // Finalmente, muestro en pantalla
          Hardware.VisualizarOculta();        
 
          // Y lo muevo si se pulsa alguna flecha del teclado
          if (Hardware.TeclaPulsada(Hardware.TECLA_DER) )
              x+=4;
          if(Hardware.TeclaPulsada(Hardware.TECLA_ARR) )
              y-=4;
 
          if (Hardware.TeclaPulsada(Hardware.TECLA_IZQ) )
              x-=4;
          if (Hardware.TeclaPulsada(Hardware.TECLA_ABA) )
              y+=4;
 
          // Y muevo siempre a los enemigos
          for (i=0; i<6; i++) 
          {
            xMurcielagos[i] += incrXMurcielagos[i];
 
            // Los murcielagos rebotan en los lados
            if ( (xMurcielagos[i] >= maxX) 
                 ||  (xMurcielagos[i] <= minX) )
              incrXMurcielagos[i] = (short) -incrXMurcielagos[i];
          }
 
          // y el segundo me persigue  
          if (x > xEnemigo2 )
            xEnemigo2 ++;
          if (x < xEnemigo2 )
            xEnemigo2 --;
 
          if( y > yEnemigo2 )
            yEnemigo2 ++;
          if ( y < yEnemigo2 )
            yEnemigo2 --;
 
          // Pausa para 25 fps
          Hardware.Pausa( 40 );
        } while (! Hardware.TeclaPulsada(Hardware.TECLA_ESC) );
 
    }
 
} /* fin de la clase Juego */
 

Siguiente entrega...