15. Recoger premios y obtener puntos

Ahora vamos a hacer que nuestro personaje pueda obtener puntos cada vez que toque un "premio"

Supone los siguientes cambios:

  • Comprobar colisiones con los premios
  • Si se toca uno, aumentarán los puntos (de modo que necesitaremos un contador de puntos)
  • El premio tocado deberá dejar de estar visible y no deberán comprobarse colisiones con él a partir de ese momento
  • ¿Qué ocurre cuando ya no quedan premios? Podrían volver a aparecer todos, podríamos pasar a otro nivel... pero de momento, en nuestro juego no ocurrirá nada

No es difícil:

Sabemos cómo hacer un contador de puntos

int puntos = 0;

Sabemos cómo comprobar colisiones básicas y cómo incrementar ese contador:

for (int i=0; i<numPremios; i++)  // Premios
{
    if ((xPremio[i] == x)  
        && (yPremio[i] == y))
    {
        puntos += 10;
    }
}

Para que los premios desaparezcan, usaremos un "array" de "booleanos", que nos diga si cada uno de ellos está visible (con valores iniciales "true"):

bool[] premioVisible = new bool[numPremios];
...
for (int i=0; i<numPremios; i++)  // Premios
{
    xPremio[i] = generador.Next(0,80);
    yPremio[i] = generador.Next(1,24);
    premioVisible[i] = true;
}

Y cada vez que toquemos uno, deberemos obtener puntos y ocultarlo. Pero hay que tener presente que si ya no está visible, no se deberá comprobar colisiones con él:

for (int i=0; i<numPremios; i++)  // Premios
{
    if ((xPremio[i] == x)  
        && (yPremio[i] == y)
        && premioVisible[i])
    {
        puntos += 10;
        premioVisible[i] = false;
    }
}

Todo junto se convertiría en algo como:

// Primer mini-esqueleto de juego en modo texto
// Versión "j"
 
using System;
using System.Threading; // Para Thread.Sleep
 
public class Juego03j
{
    public static void Main()
    {
        int vidas = 3;
        int puntos = 0;
        int xInicial = 40, yInicial = 12;
        int x=xInicial, y=yInicial; // Posición del personaje
 
        int numPremios = 10, numEnemigos = 10, numObstaculos = 20;
 
        // Reservo espacio para los datos repetitivos
        int[] xObstaculo = new int[numObstaculos]; // Obstáculos
        int[] yObstaculo = new int[numObstaculos];
 
        float[] xEnemigo = new float[numEnemigos]; // Enemigos
        float[] yEnemigo = new float[numEnemigos];
        float[] incr  = new float[numEnemigos];
 
        int[] xPremio = new int[numPremios]; // Premios
        int[] yPremio = new int[numPremios];
        bool[] premioVisible = new bool[numPremios];
 
        bool fin = false;
        ConsoleKeyInfo tecla;  // Tecla pulsada
 
        // Genero las posiciones de los elementos al azar
        Random generador = new Random();
        for (int i=0; i<numObstaculos; i++)  // Obstaculos
        {
            xObstaculo[i] = generador.Next(0,80);
            yObstaculo[i] = generador.Next(1,24);
        }
        for (int i=0; i<numEnemigos; i++)  // Enemigos
        {
            xEnemigo[i] = generador.Next(0,80);
            yEnemigo[i] = generador.Next(1,24);
            incr[i] = 0.5f;
        }
        for (int i=0; i<numPremios; i++)  // Premios
        {
            xPremio[i] = generador.Next(0,80);
            yPremio[i] = generador.Next(1,24);
            premioVisible[i] = true;
        }
 
 
 
        // ------ Bucle de juego ------
        while( ! fin  )
        {
            // -- Dibujar --
            Console.Clear();
 
            // Marcador
            Console.Write("Vidas: {0}  -  Puntos {1}", 
                vidas, puntos);
 
            for (int i=0; i<numObstaculos; i++)  // Obstáculos
            {
                Console.SetCursorPosition(
                    xObstaculo[i], yObstaculo[i]);
                Console.Write("o");
            }
 
            for (int i=0; i<numEnemigos; i++)  // Enemigos
            {
                Console.SetCursorPosition(
                    (int) xEnemigo[i], (int) yEnemigo[i]);
                Console.Write("@");
            }
 
            for (int i=0; i<numPremios; i++)  // Premios
            {
                if (premioVisible[i])
                {
                    Console.SetCursorPosition(xPremio[i], yPremio[i]);
                    Console.Write("/");
                }
            }
 
            Console.SetCursorPosition(x, y);
            Console.Write("A");
 
 
            // -- Leer teclas y calcular nueva posición --
            if (Console.KeyAvailable)
            {
                tecla = Console.ReadKey(false);
 
                if(tecla.Key == ConsoleKey.RightArrow) x++;
                if(tecla.Key == ConsoleKey.LeftArrow) x--;
                if(tecla.Key == ConsoleKey.DownArrow) y++;
                if(tecla.Key == ConsoleKey.UpArrow) y--;
            }
 
            // -- Mover enemigos, entorno --
            for (int i=0; i<numEnemigos; i++)  // Enemigos
            {
                xEnemigo[i] = xEnemigo[i] + incr[i];
                if (( (int) xEnemigo[i] == 0)
                        || ( (int) xEnemigo[i] == 79))
                    incr[i] = - incr[i];
            }
 
            // -- Colisiones, perder vidas, etc --
            for (int i=0; i<numObstaculos; i++)  // Obstáculos
            {
                if ((xObstaculo[i] == x)  
                    && (yObstaculo[i] == y))
                {
                    vidas --;
                    if (vidas == 0)
                        fin=true;
                    x = xInicial;
                    y = yInicial;
                }
            }
 
            for (int i=0; i<numEnemigos; i++)  // Enemigos
            {
                if (( (int) xEnemigo[i] == x)
                        && ( (int) yEnemigo[i] == y))
                {
                    vidas --;
                    if (vidas == 0)
                        fin=true;
                    x = xInicial;
                    y = yInicial;
                }
            }
 
            for (int i=0; i<numPremios; i++)  // Premios
            {
                if ((xPremio[i] == x)  
                    && (yPremio[i] == y)
                    && premioVisible[i])
                {
                    puntos += 10;
                    premioVisible[i] = false;
                }
            }
 
            // -- Pausa hasta el siguiente "fotograma" del juego --
            Thread.Sleep(40);
        }
    }
}
 

Ejercicio propuesto: Haz que los premios que desaparecen vuelvan a aparecer inmediatamente en una nueva posición escogida al azar.

Ejercicio propuesto (2): Haz que los premios desaparezcan uno a uno, y que cuando ya ninguno esté visible, vuelvan a aparecer todos en posiciones escogidas al azar.