¿Qué hará esta versión?

Veamos cómo hacerlo...

Mejora en la clase Mapa: obtener puntos

Por una parte, tenemos que ampliar la clase Mapa. Va a afectar a dos cosas: podremos "pisar" las casillas que contengan ciertos objetos, como las llaves, y además esas casillas deberían darnos puntos.

Para poder "pisar" esas casillas basta ampliar un poco la función "EsPosibleMover", para que contemple más tipos de casillas:

 public bool EsPosibleMover(int x, int y, int xmax, int ymax)
 {
 
     // Compruebo si choca con alguna casilla del fondo
     for (int fila = 0; fila < altoMapa; fila++)
            for (int colum = 0; colum < anchoMapa; colum++)
            {
                int posX = colum * anchoTile + margenIzqdo;
                int posY = fila * altoTile + margenSuperior;
                // Si se solapa con la posic a la que queremos mover
                if ((posX+anchoTile > x) && (posY+altoTile > y)  
                    && (xmax> posX) && (ymax > posY))
                    // Y no es espacio blanco, llave, puerta o arbol
                    if ((datosNivel[fila][colum] != ' ')                          
                        && (datosNivel[fila][colum] != 'V')  
                        && (datosNivel[fila][colum] != 'P')  
                        && (datosNivel[fila][colum] != 'A'))
                    {
                        return false;
                    }
             }
 
     return true;
 }
 

Y para obtener puntos, podemos crear una nueva función "ObtenerPuntosPosicion", muy similar a la anterior, pero que en vez de devolver "true" o "false", nos devuelva la cantidad de puntos que obtendríamos al llegar a cierta posición (por ejemplo, 10 puntos si tocamos una llave). Además de devolvernos esos 10 puntos, esta misma función se podría encargar de "borrar" la llave (reemplazando la V del array por un espacio en blanco).

La comprobación de si hemos llegado a una puerta sería similar, pero la puerta sólo debe abrirse cuando hallamos recogido todas las llaves, para lo que podemos usar un contador de llaves restantes.

De paso, podemos comprobar también si hemos tocado algún objeto "mortal", como los arbolitos o las estalactitas del techo, y hacer que devuelvan una puntuación negativa (por ejemplo, -1), que nos indique que debemos perder una vida.

Si controlamos esos 3 casos desde nuestra función "ObtenerPuntosPosicion", ésta podría quedar así:

 public int ObtenerPuntosPosicion(int x, int y, int xmax, int ymax)
 {
 
     // Compruebo si choca con alguna casilla del fondo
     for (int fila = 0; fila < altoMapa; fila++)
         for (int colum = 0; colum < anchoMapa; colum++)
         {
             int posX = colum * anchoTile + margenIzqdo;
             int posY = fila * altoTile + margenSuperior;
 
             // Si choca con la casilla que estoy mirando
             if ( (posX + anchoTile > x) && (posY + altoTile > y)
                 && (xmax > posX) && (ymax > posY))
             {
                 // Si choca con el techo o con un arbol
                 if ((datosNivel[fila][colum] == 'T') 
                          || (datosNivel[fila][colum] == 'A'))
                     return -1; // (puntuacion -1: perder vida)
 
                 // Si toca una llave
                 if (datosNivel[fila][colum] == 'V')
                 {                       
                     // datosNivel[fila][colum] = ' '; (No valido en C#: 2 pasos)
                     datosNivel[fila] = datosNivel[fila].Remove(colum, 1);
                     datosNivel[fila] = datosNivel[fila].Insert(colum, " ");
                     return 10;
                 }
 
                 // Si toca la puerta y no quedan llaves, 50 puntos
                 // y (pronto) pasar al nivel siguiente
                 if ((datosNivel[fila][colum] == 'P')
                     && (llavesRestantes == 0))
                 {
                     return 50;
                 }
 
             } // Fin de comprobacion de casilla actual
         } // Fin de "for" que revisa todas las casillas
 
     // Si llego hasta aqui, es que no hay puntos que devolver
     return 0;
 
 }
 

Cambios en la clase "Partida": ampliar ComprobarColisiones

Esto se refleja en dos cambios en la clase partida, uno pequeño y otro más grande.

El cambio pequeño es que por fin empezaremos a usar esa variable "puntos", por lo que deberíamos mostrar su valor desde "DibujarElementos", y deberemos volver a dejarlo con valor 0 cuando termine una partida.

El otro cambio es que "ComprobarColisiones" ya no sólo mirará si chocamos con el enemigo, sino también los puntos que obtendremos en la nueva posición, para sumarlos al marcador (si son positivos) o quitarnos una vida (si son negativos):

// --- Comprobar colisiones de enemigo con personaje, etc ---
 void comprobarColisiones()
{
    // Colisiones de personaje con fondo: obtener puntos o perder vida
    int puntosMovimiento = miPantallaJuego.ObtenerPuntosPosicion(
      miPersonaje.GetX(),
      miPersonaje.GetY(),
      miPersonaje.GetX() + miPersonaje.GetAncho(),
      miPersonaje.GetY() + miPersonaje.GetAlto());
 
    // Si realmente ha recogido un objeto, sumamos los puntos en el juego
    if (puntosMovimiento > 0)
    {
        puntos += puntosMovimiento;
 
        // Si ademas es una puerta, avanzamos de nivel
        if (puntosMovimiento == 50)
            //avanzarNivel()
            ;
    }
 
    // Y si es -1, ha chocaco con el fondo: igual caso que las
    // colisiones de personaje con enemigo: recolocar y perder vida
    if ((puntosMovimiento <0 ) || miPersonaje.ColisionCon(miEnemigo))
    {
        miPersonaje.Morir();
        miPersonaje.Reiniciar();
        miEnemigo.Reiniciar();
    }
 
     if (miPersonaje.GetVidas() == 0)
         partidaTerminada = true;
}
 


Como siempre, puedes descargar la versión 0.09 completa en la página del proyecto en Google Code.

Siguiente entrega...