Por Nacho Cabanes
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.
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:
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:
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...