6. Un "bucle de juego". Consola avanzada 1 - Escribir en cualquier posición
Durante varias entregas, desarrollaremos el esqueleto de un juego de plataformas básico, pero "en modo texto" (usando letras en vez de imágenes), que nos permita practicar conceptos y estructuras un poco más avanzados, pero nos permita despreocuparnos todavía de detalles más difíciles como la carga de imágenes, la realización de animación o la reproducción de sonidos.
En el primer acercamiento, nos limitaremos a mover una letra por pantalla. Primero lo haremos usando "teclas normales", y después lo mejoraremos para que se puedan usar las flechas del teclado.
Vamos con las novedades:
- Usaremos "Console.Clear();" para borrar la pantalla en cada "fotograma", y que nuestro "personaje" no deje rastro al moverse.
- Con "Console.SetCursorPosition(x, y);" podremos colocar un texto en cierta posición de pantalla. La coordenada "x" se refiere a la posición en horizontal, empezando a contar desde el extremo izquierdo de la pantalla, y típicamente valdrá de 0 a 79. La coordenada "y" indica la posición vertical, contando desde el extremo superior de la pantalla, y típicamente valdrá de 0 a 24.
- Estas dos órdenes necesitan que nuestra versión de Mono (o de la plataforma .Net) sea la 2 o superior, y deberemos compilar con "gmcs", no con "mcs". No debería suponer un problema.
- Podemos mover el personaje con teclas como QAOP (Q=arriba, A=abajo, O=izquierda, P=derecha). Las leeremos como texto (string), por lo que no hará falta convertir. Eso sí, en este primer acercamiento habrá que pulsar Intro después de cada una de esas teclas.
- Usaremos expresiones abreviadas, como "x++;" para aumentar el valor de la coordenada x (horizontal), o "y--;" para disminuir la y (vertical).
Además, vamos a hacer que nuestro juego se repita indefinidamente, con una condición como "while (1==1)", y a hacer que la parte repetitiva siga la estructura de un "bucle de juego" clásico, en el que se repiten continuamente una serie de tareas como:
- Dibujar los elementos en pantalla
- Comprobar si el usuario ha pulsado alguna tecla (o ha movido el joystick, o el ratón, o algún otro dispositivo de entrada)
- Mover los enemigos, el entorno y cualquier otro componente del juego que sea capaz de moverse por sí solo.
- Comprobar colisiones, para ver si hemos recogido algún objeto, tocado algún enemigo, si algún disparo ha impactado con algo, etc., y así poder actualizar los puntos, las vidas y el resto del estado actual del juego.
- Si queremos que la velocidad del juego sea "estable" (que no se mueva mucho más rápido en ordenadores más recientes, lo que lo haría injugable), quizá necesitemos hacer una pausa al final de cada "fotograma".
La mayoría de las tareas de este "bucle de juego" las iremos completando más adelante, y de momento quedarán como comentarios, para que el fuente "recuerde" a lo que acabará siendo.
El resultado podría ser algo como:
// Primer mini-esqueleto de juego en modo texto // Versión "a" using System; public class Juego03a { public static void Main() { string tecla; int x = 40, y=12; // Bucle de juego while( 1 == 1 ) { // Dibujar Console.Clear(); Console.SetCursorPosition(x, y); Console.Write("A"); // Leer teclas y calcular nueva posición tecla = Console.ReadLine(); if (tecla == "p") x++; if (tecla == "o") x--; if (tecla == "a") y++; if (tecla == "q") y--; // Mover enemigos, entorno // NADA // Colisiones, perder vidas, etc // NADA // Pausa hasta el siguiente "fotograma" del juego // NO TODAVIA } } }
Que en pantalla se vería:
Eso de tener que pulsar Intro después de cada tecla para moverse... no queda muy amigable. Lo podemos mejorar si accedemos directamente al teclado. Lo veremos en el siguiente apartado...
Ejercicio propuesto: Mejora el juego para que no falle cuando el usuario se intenta mover más allá del extremo de la pantalla (por la derecha, izquierda o por arriba).