35. Frontón (4): Raqueta y pelota; varias vidas

Hacer que la pelota rebote en la raqueta también es sencillo: deberemos ver si se encuentra en la misma vertical (la misma coordenada Y) y en el mismo rango de coordenadas horizontales (entre la X inicial de la raqueta y la X final de la raqueta), y en ese caso cambiaremos su incremento vertical:

if (( y == yRaqueta) && 
  (x >= xRaqueta) && (x <= xRaqueta + raqueta.Length - 1) )
{
   incrY = -incrY;
}

Esto todavía no es jugable: la pelota rebota en la raqueta, pero nunca se pierde ninguna vida. Para añadir esta mejora, podemos comprobar si se llega a la parte inferior de la pantalla, y en ese caso recolocar la pelota (tanto en su posición inicial como con su velocidad inicial) y la raqueta, restar una vida, y, en caso de que se agoten todas las vidas, comenzar un partida nueva:

if ( y >= maxY )
{
  // Recolocar pelota y raqueta
  x = 40;
  y = 12;
  xRaqueta = 39;
  yRaqueta = 22;
  incrX = 1;
  incrY = -1;
  // Compruebo final de partida
  vidas --;
  if (vidas == 0)
  {
     // Reinicio datos
     vidas = 3;
     // Pantalla de presentación
     Console.Clear();
     Console.WriteLine("Pulsa intro para jugar...");
     Console.ReadLine();
 
  }
}

El fuente completo quedaría:

// Fronton - version 5: tres vidas
 
using System;
using System.Threading;
 
public class Fronton05
{
  public static void Main()
  {
    char pelota = 'O';
    int x = 40; // Posición de la pelota
    int y = 12;
    int xRaqueta = 39;  // Posición de la raqueta
    int yRaqueta = 22;
    int vidas = 3;
    int incrX = 1; // Incremento (velocidad) de la pelota
    int incrY = -1;
    int minX = 0, maxX = 79; // Límites horizontales
    int minY = 0, maxY = 23; // Límites verticales
    bool terminado = false;
 
    string raqueta = "________";
    ConsoleKeyInfo tecla;
 
    // Ladrillos del fondo
    string[] ladrillos =
      { 
        "-------=-------=-------=-------=----------------",
        "------=-=-----=-=-----=-=-----=-=---------------",
        "-----=---=---=---=---=---=---=---=--------------",
        "----=-----=-=-----=-=-----=-=-----=-------------",
        "---=-------=-------=-------=-------=------------"
      };
 
 
    do
    {
      // Dibujo los ladrillos y la pelota
      Console.Clear();
      foreach( string filaLadrillos in ladrillos)
        Console.WriteLine( filaLadrillos );
      Console.SetCursorPosition(x, y);
      Console.Write(pelota);
      Console.SetCursorPosition(xRaqueta, yRaqueta);
      Console.Write(raqueta);
      Console.SetCursorPosition(0, maxY);
      Console.Write("Vidas: {0}", vidas);
 
      // Muevo la raqueta si se pulsa alguna tecla
      if(Console.KeyAvailable)
      {
          tecla=Console.ReadKey(false);
          if(tecla.Key == ConsoleKey.RightArrow
                      && xRaqueta < 79 - raqueta.Length)
              xRaqueta += 2;
          if(tecla.Key == ConsoleKey.LeftArrow
                      && xRaqueta > 2)
              xRaqueta -= 2;
      }
 
      // Compruebo colisiones con el fondo
      if ( ( y < ladrillos.Length)// Si estoy en vertical dentro del fondo
      && ( x < ladrillos[0].Length) // Y en horizontal
      && (ladrillos[y][x] != ' ')) // Y hay ladrillo
      {
        incrY = - incrY;
        // Borrar: no puedo hacer "ladrillos[y][x] = ' ';"
        ladrillos[y] = ladrillos[y].Remove(x, 1);
        ladrillos[y] = ladrillos[y].Insert(x, " ");
      }
      // Y colisiones con la raqueta
      if (( y == yRaqueta) && 
        (x >= xRaqueta) && (x <= xRaqueta + raqueta.Length - 1) )
      {
         incrY = -incrY;
      }
 
      // Compruebo si llego al límite de la pantalla
      // Si se sale por abajo...
      if ( y >= maxY )
      {
        // Recolocar pelota y raqueta
        x = 40;
        y = 12;
        xRaqueta = 39;
        yRaqueta = 22;
        incrX = 1;
        incrY = -1;
        // Compruebo final de partida
        vidas --;
        if (vidas == 0)
        {
           // Reinicio datos
           vidas = 3;
           // Pantalla de presentación
           Console.Clear();
           Console.WriteLine("Pulsa intro para jugar...");
           Console.ReadLine();
 
        }
      }
      // Si llega a un extremo sin salir por abajo: rebota
      if ( (x <= minX) || (x >= maxX) )
        incrX = -incrX;
      if  (y <= minY)
        incrY = -incrY;
 
      // Y paso a la siguiente posición
      x += incrX;
      y += incrY;
 
      // Y espero un poco hasta el siguiente fotograma
      Thread.Sleep( 40 );
    }
    while (!terminado);
  }
}
 

Ejercicio propuesto: Mejora este fuente para que vuelvan a aparecer los ladrillos cuando se hayan roto todos. Añade un marcador que muestre también los puntos que se van obteniendo.