18. Presentación. Poder volver a jugar

Ahora mismo, cuando termina la partida, también termina todo el juego. Pero esto no es lo habitual: en un "juego real suele haber una pantalla de presentación previa, y tras terminar una partida se vuelve a esa pantalla de presentación y se puede comenzar una nueva partida.

Vamos a añadir esa posibilidad a nuestro juego...

No debería ser especialmente complicado:

  • Ahora el "bucle de juego" (que representa el transcurso de una partida) deberá estar rodeado por un nuevo "do...while", que represente toda una sesión de juego.
  • Antes de que comience el bucle de juego, se mostrará una pantalla que dé al usuario una serie de opciones (como mínimo, la de comenzar una nueva partida y la de abandonar el programa).
  • Esa parte repetitiva debe incluir también las tareas que se deben volver a realizar cada vez antes de cada nueva "partida", como dejar las vidas en su valor inicial (3), los puntos también con su valor inicial (0), todos los premios visibles, volver a generar posiciones al azar para todos los elementos, etc.

// Primer mini-esqueleto de juego en modo texto
// Versión "m"
 
using System;
using System.Threading; // Para Thread.Sleep
 
public class Juego03m
{
    struct ElemGrafico {
        public float x;
        public float y;
        public int xInicial;
        public int yInicial;
        public float incrX;
        public float incrY;
        public char simbolo;
        public ConsoleColor color;
        public bool visible;
    }
 
    public static void Main()
    {
        ElemGrafico personaje;
        personaje.xInicial = 40;
        personaje.yInicial = 12;
        personaje.x = personaje.xInicial;
        personaje.y = personaje.yInicial;
        personaje.simbolo = 'A';
        personaje.color = ConsoleColor.Yellow;
 
        int numPremios = 10, numEnemigos = 10, numObstaculos = 20;
 
        // Reservo espacio para los datos repetitivos
        ElemGrafico[] obstaculos = new ElemGrafico[numObstaculos];
        ElemGrafico[] enemigos = new ElemGrafico[numEnemigos];
        ElemGrafico[] premios = new ElemGrafico[numPremios];
 
        bool juegoTerminado = false;
        int vidas;
        int puntos;
        bool partidaTerminada;
        ConsoleKeyInfo tecla;  // Tecla pulsada
        Random generador = new Random();
 
        while (! juegoTerminado )
        {
 
            // En cada partida, hay que reiniciar ciertas variables
            vidas = 3;
            puntos = 0;
            partidaTerminada = false; 
 
            // Genero las posiciones de los elementos al azar
            for (int i=0; i<numObstaculos; i++)  // Obstaculos
            {
                obstaculos[i].x = generador.Next(0,80);
                obstaculos[i].y = generador.Next(1,24);
                obstaculos[i].simbolo = 'o';
                obstaculos[i].color = ConsoleColor.Red;
            }
 
            for (int i=0; i<numEnemigos; i++)  // Enemigos
            {
                enemigos[i].x = generador.Next(0,80);
                enemigos[i].y = generador.Next(1,24);
                enemigos[i].incrX = 0.5f;
                enemigos[i].simbolo = '@';
                enemigos[i].color = ConsoleColor.Blue;
            }
 
            for (int i=0; i<numPremios; i++)  // Premios
            {
                premios[i].x = generador.Next(0,80);
                premios[i].y = generador.Next(1,24);
                premios[i].simbolo = '/';
                premios[i].color = ConsoleColor.White;
                premios[i].visible = true;
            }
 
            // ---- Pantalla de presentación ----
            Console.Clear();
            Console.ForegroundColor = ConsoleColor.White;
            Console.SetCursorPosition(34,10);
            Console.Write("Jueguecillo");
            Console.SetCursorPosition(31,12);
            Console.Write("Escoja una opción:");
            Console.SetCursorPosition(15,17);
            Console.Write("1.- Jugar una partida");
            Console.SetCursorPosition(15,19);
            Console.Write("0.- Salir ");
            tecla = Console.ReadKey(false);
            if (tecla.KeyChar == '0')
            {
                partidaTerminada = true;
                juegoTerminado = true;
            }
 
 
 
            // ------ Bucle de juego ------
            while( ! partidaTerminada  )
            {
                // -- Dibujar --
                Console.Clear();
 
                // Marcador
                Console.Write("Vidas: {0}  -  Puntos {1}", 
                    vidas, puntos);
 
                for (int i=0; i<numObstaculos; i++)  // Obstáculos
                {
                    Console.SetCursorPosition(
                        (int) obstaculos[i].x, (int) obstaculos[i].y);
                    Console.ForegroundColor =  obstaculos[i].color;
                    Console.Write( obstaculos[i].simbolo );
                }
 
                for (int i=0; i<numEnemigos; i++)  // Enemigos
                {
                    Console.SetCursorPosition(
                        (int) enemigos[i].x, (int) enemigos[i].y);
                    Console.ForegroundColor =  enemigos[i].color;
                    Console.Write( enemigos[i].simbolo );
                }
 
                for (int i=0; i<numPremios; i++)  // Premios
                {
                    if (premios[i].visible)
                    {
                        Console.SetCursorPosition(
                            (int) premios[i].x, (int) premios[i].y);
                        Console.ForegroundColor =  premios[i].color;
                        Console.Write( premios[i].simbolo );
                    }
                }
 
                Console.SetCursorPosition(
                    (int) personaje.x, (int) personaje.y);
                Console.ForegroundColor =  personaje.color;
                Console.Write( personaje.simbolo );
 
 
                // -- Leer teclas y calcular nueva posición --
                if (Console.KeyAvailable)
                {
                    tecla = Console.ReadKey(false);
 
                    if(tecla.Key == ConsoleKey.RightArrow) personaje.x++;
                    if(tecla.Key == ConsoleKey.LeftArrow) personaje.x--;
                    if(tecla.Key == ConsoleKey.DownArrow) personaje.y++;
                    if(tecla.Key == ConsoleKey.UpArrow) personaje.y--;
                }
 
                // -- Mover enemigos, entorno --
                for (int i=0; i<numEnemigos; i++)  // Enemigos
                {
                    enemigos[i].x = enemigos[i].x + enemigos[i].incrX;
                    if (( (int) enemigos[i].x == 0)
                            || ( (int) enemigos[i].x == 79))
                        enemigos[i].incrX = - enemigos[i].incrX;
                }
 
                // -- Colisiones, perder vidas, etc --
                for (int i=0; i<numObstaculos; i++)  // Obstáculos
                {
                    if ((obstaculos[i].x == personaje.x)  
                        && (obstaculos[i].y == personaje.y))
                    {
                        vidas --;
                        if (vidas == 0)
                            partidaTerminada=true;
                        personaje.x = personaje.xInicial;
                        personaje.y = personaje.yInicial;
                    }
                }
 
                for (int i=0; i<numPremios; i++)  // Obstáculos
                {
                    if ((premios[i].x == personaje.x)  
                        && (premios[i].y == personaje.y)
                        && premios[i].visible )
                    {
                        puntos += 10;
                        premios[i].visible = false;
                    }
                }
 
                for (int i=0; i<numEnemigos; i++)  // Enemigos
                {
                    if (( (int) enemigos[i].x == personaje.x)
                            && ( (int) enemigos[i].y == personaje.y))
                    {
                        vidas --;
                        if (vidas == 0)
                            partidaTerminada=true;
                        personaje.x = personaje.xInicial;
                        personaje.y = personaje.yInicial;
                    }
                }
 
                // -- Pausa hasta el siguiente "fotograma" del juego --
                Thread.Sleep(40);
 
            } // Fin del bucle de juego
 
        }     // Fin de partida
 
    }         // Fin de Main
}
 

Ejercicio propuesto: Añade al menú una nueva opción que permita mostrar una ayuda al usuario, que le diga qué debe hacer en el juego (recoger premios, esquivar obstáculos y enemigos, etc).

Ejercicio propuesto (2): Añade una opción que "memorice" la puntuación más alta conseguida durante una sesión de juego (varias partidas consecutivas).