06 diciembre 2008

Remake (parcial) de Fruity Frank... 19 - Un personaje que dispara

Ahora vamos a añadir la posibilidad de que nuestro personaje "dispare". La idea básica es la misma que con los enemigos: el disparo será otro elemento que podrá estar activo o no estarlo, y que deberá irse moviendo en cada fotograma.

En el juego Fruity Frank original, el disparo era una "pelota" que salía en la dirección en la que miraba nuestro personaje, que rebotaba con las paredes y que podía volver a nuestras manos. En esta primera aproximación vamos a hacer algo mucho más sencillo: el "disparo" siempre saldrá hacia la derecha, y avanzará hasta que choque con un enemigo o se salga de la pantalla. Además, sólo podrá haber un disparo activo en cada momento (si pudiera haber varios, deberíamos guardarlos en alguna estructura repetitiva, como un Array).

Esto supone varios cambios en el fuente:

  • Habrá que declarar ciertas variables adicionales al principio del programa, que necesitaremos para el control del disparo:


      // Datos del disparo
bool disparoActivo = false;
short xDisparo, yDisparo;
short anchoDisparo=28, altoDisparo=24;


  • Cuando dibujamos cosas en pantalla (función dibujarPantalla), también habrá que dibujar el disparo:


      // Disparo
if (disparoActivo)
DibujarImagenOculta(disparo, xDisparo, yDisparo);


  • Igual que teníamos una función para mover los enemigos, necesitaremos otra para mover el disparo:


      void moverDisparo()
{
// De momento el disparo se mueve solo a la derecha, 5 pixeles
if (disparoActivo)
xDisparo += 5;
if (xDisparo > xFinPantalla)
disparoActivo = false;
}


  • Cuando comprobemos colisiones (función comprobarColisiones), habrá que mirar también si la pelota choca con algún enemigo; si es así, eliminaremos el enemigo y la pelota. (Entonces la pelota pasaría a estar disponible nuevamente, algo que tampoco ocurría en el Fruity original, en el que la pelota tardaba un cierto tiempo en volver a ser utilizable):


      // Veo si el disparo mata algun enemigo
for (i=0; i<NUMENEMIGOS; i++)
if (enemigos[i].activo)
{
if (Colision(enemigos[i].x, enemigos[i].y,
enemigos[i].ancho, enemigos[i].alto,
xDisparo, yDisparo,
anchoDisparo, altoDisparo))
{
enemigos[i].activo = false; // Desaparece el enemigo
disparoActivo = false; // Y el disparo
}
}


  • Incluso, al cambiar de nivel, o cuando nos mate un enemigo, habrá que indicar que no hay disparo activo: quedaría "feo" que disparásemos, cambiáramos de nivel y se viera todavía la pelota del nivel anterior moviéndose por ahí. Esto debería hacerse en "prepararNivel" y en "perderVida".



  • Y, por supuesto, habrá que buscar una imagen que represente ese disparo.



Como siempre, todo el fuente del proyecto está en: code.google.com/p/fruityfrank