22. Imagen de fondo para la presentación
Antes de hacer cosas más avanzadas, vamos a incluir una imagen como fondo de la presentación, que nos permita repasar la forma de cargar imágenes y de mostrarlas en pantalla.
Hasta ahora nuestra presentación contenía apenas 3 textos:
Ahora vamos a hacer que aparezca una imagen de fondo, para que sea un poco menos "sosa".
Para cargar la imagen podemos crear un nuevo elemento de tipo "Imagen", indicando el nombre de fichero que contiene esa imagen:
Imagen fondoPresentacion = new Imagen("present.jpg");
Y si la imagen es de tamaño 800x600, que es el tamaño de nuestra pantalla, la dibujaríamos en las coordenadas (0,0), antes de escribir los textos (para que no "los tape"):
fondoPresentacion.DibujarOculta(0,0);
Esto se haría antes de la parte repetitiva que comprueba pulsaciones de teclas, porque no tiene sentido cargar la imagen múltiples veces:
public static void MostrarPresentacion() { Imagen fondoPresentacion = new Imagen("present.jpg"); // ---- Pantalla de presentación -- Hardware.BorrarPantallaOculta(0,0,0); // Pantalla de fondo fondoPresentacion.DibujarOculta(0,0); // Marcador Hardware.EscribirTextoOculta("Jueguecillo", 340,200, // Coordenadas 255, 255, 255, // Colores tipoDeLetra); ...
El programa completo, que no tiene más cambios que esos, quedaría así:
// Primer mini-esqueleto de juego en modo gráfico // Versión "b" using System; using System.Threading; // Para Thread.Sleep public class Juego05b { struct ElemGrafico { public int x; public int y; public int xInicial; public int yInicial; public int incrX; public int incrY; public Imagen imagen; public bool visible; } static ElemGrafico personaje; static Fuente tipoDeLetra; static int numPremios, numEnemigos, numObstaculos; static ElemGrafico[] obstaculos; static ElemGrafico[] enemigos; static ElemGrafico[] premios; static bool juegoTerminado; static int vidas; static int puntos; static bool partidaTerminada; static Random generador; public static void InicializarJuego() { // Entrar a modo grafico 800x600 bool pantallaCompleta = false; Hardware.Inicializar(800, 600, 24, pantallaCompleta); // Resto de inicializacion tipoDeLetra = new Fuente("FreeSansBold.ttf", 18); juegoTerminado = false; numPremios = 10; numEnemigos = 10; numObstaculos = 20; obstaculos = new ElemGrafico[numObstaculos]; enemigos = new ElemGrafico[numEnemigos]; premios = new ElemGrafico[numPremios]; generador = new Random(); } public static void InicializarPartida() { // En cada partida, hay que reiniciar ciertas variables vidas = 3; puntos = 0; partidaTerminada = false; personaje.xInicial = 400; personaje.yInicial = 300; personaje.x = personaje.xInicial; personaje.y = personaje.yInicial; personaje.incrX = 10; personaje.incrY = 10; personaje.imagen = new Imagen("personaje.png"); // Genero las posiciones de los elementos al azar for (int i=0; i<numObstaculos; i++) // Obstaculos { obstaculos[i].x = generador.Next(50,700); obstaculos[i].y = generador.Next(30,550); obstaculos[i].imagen = new Imagen("obstaculo.png"); } for (int i=0; i<numEnemigos; i++) // Enemigos { enemigos[i].x = generador.Next(50,700); enemigos[i].y = generador.Next(30,550); enemigos[i].incrX = 5; enemigos[i].imagen = new Imagen("enemigo.png"); } for (int i=0; i<numPremios; i++) // Premios { premios[i].x = generador.Next(50,700); premios[i].y = generador.Next(30,550); premios[i].imagen = new Imagen("premio.png"); premios[i].visible = true; } } public static void MostrarPresentacion() { // Cargo la imagen de la presentación Imagen fondo = new Imagen("present.jpg"); // ---- Pantalla de presentación -- Hardware.BorrarPantallaOculta(0,0,0); // Fondo de la presentación fondo.DibujarOculta(0,0); // Marcador Hardware.EscribirTextoOculta("Jueguecillo", 340,200, // Coordenadas 255, 255, 255, // Colores tipoDeLetra); Hardware.EscribirTextoOculta("Escoja una opción:", 310,300, // Coordenadas 200, 200, 200, // Colores tipoDeLetra); Hardware.EscribirTextoOculta("1.- Jugar una partida", 150,390, // Coordenadas 200, 200, 200, // Colores tipoDeLetra); Hardware.EscribirTextoOculta("0.- Salir", 150,430, // Coordenadas 200, 200, 200, // Colores tipoDeLetra); Hardware.VisualizarOculta(); bool finPresentacion = false; do { Hardware.Pausa( 20 ); if (Hardware.TeclaPulsada(Hardware.TECLA_1) ) finPresentacion = true; if (Hardware.TeclaPulsada(Hardware.TECLA_0) ) { finPresentacion = true; partidaTerminada = true; juegoTerminado = true; } } while (! finPresentacion ); } public static void Dibujar() { // -- Dibujar -- Hardware.BorrarPantallaOculta(0,0,0); // Marcador Hardware.EscribirTextoOculta("Vidas Puntos", 0,0, // Coordenadas 255, 255, 255, // Colores tipoDeLetra); Hardware.EscribirTextoOculta( Convert.ToString(vidas), 70,0, // Coordenadas 200, 200, 200, // Colores tipoDeLetra); Hardware.EscribirTextoOculta( Convert.ToString(puntos), 190,0, // Coordenadas 200, 200, 200, // Colores tipoDeLetra); for (int i=0; i<numObstaculos; i++) // Obstáculos { obstaculos[i].imagen.DibujarOculta( (int) obstaculos[i].x, (int) obstaculos[i].y); } for (int i=0; i<numEnemigos; i++) // Enemigos { enemigos[i].imagen.DibujarOculta( (int) enemigos[i].x, (int) enemigos[i].y); } for (int i=0; i<numPremios; i++) // Premios { if (premios[i].visible) { premios[i].imagen.DibujarOculta( premios[i].x, premios[i].y); } } personaje.imagen.DibujarOculta( personaje.x, personaje.y); // Finalmente, muestro en pantalla Hardware.VisualizarOculta(); } public static void ComprobarTeclas() { // -- Leer teclas y calcular nueva posición -- if (Hardware.TeclaPulsada(Hardware.TECLA_ESC) ) partidaTerminada = true; if (Hardware.TeclaPulsada(Hardware.TECLA_DER) ) personaje.x += personaje.incrX; if (Hardware.TeclaPulsada(Hardware.TECLA_IZQ) ) personaje.x -= personaje.incrX; if (Hardware.TeclaPulsada(Hardware.TECLA_ARR) ) personaje.y -= personaje.incrY; if (Hardware.TeclaPulsada(Hardware.TECLA_ABA) ) personaje.y += personaje.incrY; } public static void MoverElementos() { // -- 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 <= 50) || ( (int) enemigos[i].x >= 700)) enemigos[i].incrX = - enemigos[i].incrX; } } public static void ComprobarColisiones() { // -- 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; } } } public static void PausaFotograma() { // -- Pausa hasta el siguiente "fotograma" del juego -- Hardware.Pausa( 20 ); } public static void Main() { InicializarJuego(); while (! juegoTerminado ) { InicializarPartida(); MostrarPresentacion(); // ------ Bucle de juego ------ while( ! partidaTerminada ) { Dibujar(); ComprobarTeclas(); MoverElementos(); ComprobarColisiones(); PausaFotograma(); } // Fin del bucle de juego } // Fin de partida } // Fin de Main }
Ejercicio propuesto: Esto se puede afinar un poco más: no es necesario cargar la imagen cada vez que se entra a la presentación, basta con cargarla una única vez cuando se inicializa el juego. Haz una versión mejorada del programa que incluya este cambio.
Ejercicio propuesto: Haz que las imágenes de personaje, enemigos, premios, etc. se carguen también en el momento de inicializar el juego, no cada vez que va a comenzar una nueva partida.
(Nota: si quieres ver cómo quedaría el fuente con estos cambios propuestos... tendrás que mirar en el siguiente apartado, que partirá de ese punto).