Por Nacho Cabanes
Vamos a hacer que el fuente sea un poco más modular, descomponiéndolo en funciones. Para eso, intentaremos que la parte principal del programa tenga una apariencia similar a la de un "bucle de juego" clásico:
repetir
comprobar teclas
calcular siguiente posición de elementos
comprobar colisiones entre elementos
dibujar elementos en pantalla
pausa hasta tiempo final de fotograma
hasta final de partida
Este algoritmo se podría reescribir en forma de fuente de C# así:
void buclePrincipal() { partidaTerminada = false; do { comprobarTeclas(); moverElementos(); comprobarColisiones(); dibujarElementos(); pausaFotograma(); } while (! partidaTerminada); }
De modo que "Main" se limitaría a inicializar los datos (entrar a modo gráfico, cargar imágenes), mostrar la presentación y lanzar este bucle principal:
void Main() { inicializar(); mostrarPresentacion(); buclePrincipal(); }
Es poco más que redistribuir el fuente: fragmentos que antes eran parte de "Main", ahora pertenecerán a ""dibujarElementos", "comprobarTeclas", etc. Las variables que sólo afecten sólo a uno de esos fragmentos (casi ninguna por ahora) podrán quedar como variables locales en una función; la mayoría de variables, que son compartidas por más de una función, quedarán fuera de todas ellas (incluido "Main"), y ahora deberán estar precedidas por la palabra "static" (más adelante veremos por qué).
El fuente completo podría quedar así (como siempre, el fichero ZIP que contiene las imágenes, DLLs y demás ficheros necesarios los tienes en la entrega 1):
/** * 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 imagen de fondo 0.07 04-Nov-2009 Nacho Cabanes El personaje se mueve solo por los "huecos" Eliminados los enemigos (por ahora) Renombradas variables i,j a fila,colum 0.08 10-Nov-2009 Nacho Cabanes Varias funciones para que el fuente sea mas modular ---------------------------------------------------- */ using System; // Para numeros aleatorios: System.Random public class Juego { // Variables que usaremos: una imagen y un tipo de letra static ElemGrafico imagenPersonaje, presentacion; static ElemGrafico imagenFondoHoriz,imagenFondoHorizAcido, imagenFondoVert, imagenEscalera; static Fuente fuente18; static int fila, colum; // Para recorrer static short x=1, y=1; static int minX = 0, maxX = 6, minY = 0, maxY = 6; static int filasPantalla = 7; static int columnasPantalla = 7; static 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} }; static bool partidaTerminada; static void inicializar() { // 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"); 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"); } static void mostrarPresentacion() { //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); } static void comprobarTeclas() { // Y lo muevo si se pulsa alguna flecha del teclado if (Hardware.TeclaPulsada(Hardware.TECLA_DER) ) if (x < maxX) if ((mapa[y,x+1] == 0) // Espacio en blanco || (mapa[y,x+1] == 4) )// Escalera x++; if(Hardware.TeclaPulsada(Hardware.TECLA_ARR) ) if ( y > 0) if ((mapa[y-1,x] == 0) // Espacio en blanco || (mapa[y-1,x] == 4) )// Escalera y--; if (Hardware.TeclaPulsada(Hardware.TECLA_IZQ) ) if ( x > 0) if ((mapa[y,x-1] == 0) // Espacio en blanco || (mapa[y,x-1] == 4) )// Escalera x--; if (Hardware.TeclaPulsada(Hardware.TECLA_ABA) ) if (y < maxY) if ((mapa[y+1,x] == 0) // Espacio en blanco || (mapa[y+1,x] == 4) )// Escalera y++; if (Hardware.TeclaPulsada(Hardware.TECLA_ESC)) partidaTerminada = true; } static void moverElementos() { // Nada que mover en esta version } static void comprobarColisiones() { // Nada que comprobar en esta version } static void dibujarElementos() { Hardware.BorrarPantallaOculta(0,0,0); // Dibujo el fondo de la pantalla for (fila=0; fila<filasPantalla; fila++) for (colum=0; colum<columnasPantalla; colum++) switch (mapa[fila,colum]) { case 0: // Espacio en blanco, no dibujo nada break; case 1: imagenFondoHoriz.MoverA( (short) (colum*70) , (short) (fila*50)); imagenFondoHoriz.DibujarOculta(); break; case 2: imagenFondoHorizAcido.MoverA( (short) (colum*70) , (short) (fila*50)); imagenFondoHorizAcido.DibujarOculta(); break; case 3: imagenFondoVert.MoverA( (short) (colum*70) , (short) (fila*50)); imagenFondoVert.DibujarOculta(); break; case 4: imagenEscalera.MoverA( (short) (colum*70) , (short) (fila*50)); imagenEscalera.DibujarOculta(); break; } // Dibujo el personaje, el enemigo y un texto en la pantalla oculta imagenPersonaje.MoverA( (short) (x*70) , (short) (y*50) ); imagenPersonaje.DibujarOculta(); Hardware.EscribirTextoOculta( "Pulsa ESC para salir", 300, 500, 0xAA, 0xAA, 0xAA, fuente18); // Finalmente, muestro en pantalla Hardware.VisualizarOculta(); } static void pausaFotograma() { // Pausa para 25 fps Hardware.Pausa( 40 ); } static void buclePrincipal() { partidaTerminada = false; do { comprobarTeclas(); moverElementos(); comprobarColisiones(); dibujarElementos(); pausaFotograma(); } while (! partidaTerminada); } public static void Main() { inicializar(); mostrarPresentacion(); buclePrincipal(); } } /* fin de la clase Juego */Siguiente entrega...