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.