Disparar a matar a la cara hasta que llore (el nombre me lo he currado menos que el juego xd):
La mecanica del juego es sencilla, tienes 11 balas y tienes que matar al muñequito que no para de moverse.
Si lo matas, vuelves a tener 11 balas para matar a otro enemigo mas rapido.
Si pierdes las 11 balas pierdes.
Imagenes:



Descarga:
http://www.megaupload.com/?d=M8PFOMF0
Codigo:
- Código: Seleccionar todo
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
#include "SDL_ttf.h"
#include <conio.h>
#include <time.h>
#include <stdlib.h>
void comprovar_surface(SDL_Surface * superficie);
void actualizar_imagen_balas(int balas, SDL_Surface * screen, SDL_Surface * bala);
class enemigo
{
public:
void mover(int velocidad, int * direccion);
int hp;
int caraActual;
int velocidad;
SDL_Rect rect;
SDL_Surface * cara[4];
SDL_Surface * caraLimpia[4];
};
int main(int arcg, char *argv[])
{
srand(time(NULL)); //Funcion para hacer que los numeros sean totalmente aleatoriios
///////////////
// INICIANDO
///////////////
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0) ///INICIAR SDL VIDEO Y AUDIO COMPROBANDO ERRORES
{
printf("Error SDL_Init: %s", SDL_GetError());
getch();
exit(1);
}
atexit(SDL_Quit); //Cuando acabe el programa, se cierra SDL
SDL_Surface * screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE); //Creo la que sera la pantalla del juego
comprovar_surface(screen);
enemigo enemigo1; //creo un enemigo
///TTF
TTF_Init();
TTF_Font * fuenteOtra = TTF_OpenFont("times.ttf", 50);
SDL_Color colorFuente = {0,0,0};
SDL_Surface * otraVez;
otraVez = TTF_RenderText_Blended(fuenteOtra, "Otra Vez?", colorFuente);
TTF_Font * fuentePuntos = TTF_OpenFont("times.ttf", 20);
SDL_Surface * puntosLetras = TTF_RenderText_Blended(fuentePuntos, "Puntos: ", colorFuente);
SDL_Surface * puntosNumeros = TTF_RenderText_Blended(fuentePuntos, "10 ", colorFuente);
///////////////
// SONIDOS
///////////////
Mix_OpenAudio(44100, AUDIO_S16SYS, 2, 4096); // Abrir audio
Mix_Chunk * sonidoBala = Mix_LoadWAV("disparo.wav"); //Cargar sonidos
Mix_Chunk * sonidoFondo = Mix_LoadWAV("fondo.wav");
Mix_Chunk * wow = Mix_LoadWAV("wow.wav");
Mix_Chunk * doh = Mix_LoadWAV("doh.wav");
///////////////
// CARGAR IMAGENES
//////////////
SDL_Surface * fondo = IMG_Load("fondo.png");
comprovar_surface(fondo);
SDL_Surface * mirilla = IMG_Load("mirilla.png");
comprovar_surface(mirilla);
SDL_Surface * balazo = IMG_Load("balazo.png");
comprovar_surface(balazo);
SDL_Surface * bala = IMG_Load("bala.png");
comprovar_surface(bala);
SDL_Surface * gameover = IMG_Load("gameover1.png");
comprovar_surface(gameover);
//Caras del enemigo
enemigo1.cara[0] = IMG_Load("feliz.png");
comprovar_surface(enemigo1.cara[0]);
enemigo1.cara[1] = IMG_Load("triste.png");
comprovar_surface(enemigo1.cara[1]);
enemigo1.cara[2] = IMG_Load("muytriste.png");
comprovar_surface(enemigo1.cara[2]);
enemigo1.cara[3] = IMG_Load("llorando.png");
comprovar_surface(enemigo1.cara[3]);
//Caras limpias para renovarlas cuando se pase de puntos
enemigo1.caraLimpia[0] = IMG_Load("feliz.png");
comprovar_surface(enemigo1.caraLimpia[0]);
enemigo1.caraLimpia[1] = IMG_Load("triste.png");
comprovar_surface(enemigo1.caraLimpia[1]);
enemigo1.caraLimpia[2] = IMG_Load("muytriste.png");
comprovar_surface(enemigo1.caraLimpia[2]);
enemigo1.caraLimpia[3] = IMG_Load("llorando.png");
comprovar_surface(enemigo1.caraLimpia[3]);
//Botones
SDL_Surface * botonSi = IMG_Load("botonsi.png");
comprovar_surface(botonSi);
SDL_Surface * botonNo = IMG_Load("botonno.png");
comprovar_surface(botonNo);
//Efectos especiales
SDL_Surface * enemigoBlanco = IMG_Load("blanco.png");
comprovar_surface(enemigoBlanco);
SDL_Surface * chorrito = IMG_Load("chorrito1.png");
comprovar_surface(chorrito);
///////////////
// VARIABLES INICIALES
///////////////
//VARIABLES PREVIAS
Uint8 * tecla;
SDL_Event evento; //Variable de la estructura event para eventos del raton
SDL_Rect rectMirilla; //Rectangulo para la posicion de la mirilla
SDL_Rect rectBalazoCara; //Rectangulo para la posicion de la sangre en la cara del enemigo
SDL_Rect rectGameover;
SDL_Rect rectBotonSi;
SDL_Rect rectBotonNo;
SDL_Rect rectOtraVez;
SDL_Rect rectPuntosLetras;
SDL_Rect rectPuntosNumeros;
rectPuntosLetras.x = 10;
rectPuntosLetras.y = 570;
rectPuntosNumeros.x = 80;
rectPuntosNumeros.y = 570;
rectOtraVez.x = 180;
rectOtraVez.y = 400;
rectBotonSi.x = 390;
rectBotonSi.y = 400;
rectBotonNo.x = 500;
rectBotonNo.y = 400;
rectGameover.x = 100;
rectGameover.y = 0;
int puntos = 0;
char buffer[10]; //para guardar los puntos en tipo char
int balas = 11;
enemigo1.rect.x = 0; //Posicion anemigo
enemigo1.rect.y = 200;
enemigo1.hp = 100;
enemigo1.caraActual = 0;
enemigo1.velocidad = 4;
int direccion; //Variable para la direccion hacia donde se mueve el enemigo, se acctualiza en cada llamada a mover();
int ratonx; //Variables para poder pasarselas a SDL_GetMouseState
int ratony;
bool done = false; //Mientras done sea falso, el juego se ejecuta
Mix_PlayChannel(-1, sonidoFondo, -1); //Musica de fondo, empieza cuando empieza el game loop
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///GAME LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOP
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
while(!done)
{
SDL_PumpEvents(); //Eventos teclado
tecla = SDL_GetKeyState(0);
SDL_PollEvent(&evento); //comprobar eventos
SDL_GetMouseState(&ratonx, &ratony); //Pasar posicion raton
rectMirilla.x = ratonx -50; //Ajustar punto del medio de la mirilla con el raton
rectMirilla.y = ratony -50;
if(evento.type == SDL_MOUSEBUTTONDOWN) //SI HAY CLICK / DISPARO
{
balas --; //En el momento en que se dispara se pierde una bala
///Verifico que el raton este encima de la imagen del enemigo en el momento de la pulsacion del boton
if( (ratonx >= enemigo1.rect.x && ratony >= enemigo1.rect.y) && (ratonx <= (enemigo1.rect.w + enemigo1.rect.x) && ratony <= (enemigo1.rect.h+enemigo1.rect.y) ))
{
enemigo1.hp -= 50; //Quitar vida al enemigo y comprovar si ha muerto
if(enemigo1.hp <= 0)
{
enemigo1.caraActual++; //Si ha muerto pasa a la siguiente face (a la siguiente cara)
///RENOVAR CARA USADA
switch(enemigo1.caraActual) //En el array caraLimpia se almacena le imagen sin sangre de cada cara
{
case 1:
SDL_BlitSurface(enemigo1.caraLimpia[0], NULL, enemigo1.cara[0], NULL); //Si pasamos a cara[1], renovamos la cara[0]
break;
case 2:
SDL_BlitSurface(enemigo1.caraLimpia[1], NULL, enemigo1.cara[1], NULL); //Si pasamos a cara[2], renovamos la cara[1]
break;
case 3:
SDL_BlitSurface(enemigo1.caraLimpia[2], NULL, enemigo1.cara[2], NULL); //Si pasamos a cara[3], renovamos la cara[2]
break;
case 4:
SDL_BlitSurface(enemigo1.caraLimpia[3], NULL, enemigo1.cara[3], NULL); //Si volvemos a la cara[0](vease mas abajo) renovamos la cara [3]
break;
}
if(enemigo1.caraActual == 4) //Si caraActual es 4, pasamos a la siguiente puntos
{
///ANIMACION MUERTE
Mix_PlayChannel(-1, wow, 0);
SDL_BlitSurface(fondo, NULL, screen, NULL); ///Actualizar pantalla
SDL_BlitSurface(enemigoBlanco, NULL, screen, &enemigo1.rect);
SDL_BlitSurface(mirilla, NULL, screen, &rectMirilla);
SDL_Flip(screen);
SDL_Delay(80);
SDL_BlitSurface(fondo, NULL, screen, NULL); ///Actualizar pantalla
SDL_BlitSurface(enemigo1.cara[enemigo1.caraActual], NULL, screen, &enemigo1.rect);
SDL_BlitSurface(mirilla, NULL, screen, &rectMirilla);
SDL_Flip(screen);
SDL_Delay(80);
SDL_BlitSurface(fondo, NULL, screen, NULL); ///Actualizar pantalla
SDL_BlitSurface(enemigoBlanco, NULL, screen, &enemigo1.rect);
SDL_BlitSurface(mirilla, NULL, screen, &rectMirilla);
SDL_Flip(screen);
SDL_Delay(80);
/////ACTUALIZAR VARIABLES
if(balas >= 1) puntos = puntos + balas;
puntos++;
enemigo1.velocidad++;
enemigo1.hp = 100;
enemigo1.caraActual = 0;
balas = 11;
continue;
}
enemigo1.hp = 100; //Despues de pasar a la siguiente fase vuelve a tener toda la vida
}
rectBalazoCara.x = rectMirilla.x - enemigo1.rect.x; //Coordenadas donde ira el chorrito de sangre en la cara
rectBalazoCara.y = rectMirilla.y - enemigo1.rect.y;
SDL_BlitSurface(chorrito, NULL, enemigo1.cara[enemigo1.caraActual], &rectBalazoCara);
}
else
{
SDL_BlitSurface(balazo, NULL, fondo, &rectMirilla); //Pintar balazo en la pared
}
Mix_PlayChannel(-1, sonidoBala, 0); //Sonido balazo
evento.type = SDL_NOEVENT; //Limpiar Buffer eventos
}
if(tecla[SDLK_ESCAPE])
{
done = true; //Si se pulsa scape, se sale del loop
}
enemigo1.mover(enemigo1.velocidad, &direccion); //Cambiar posicion del enemigo
///////////////////////////////////////////////////////////////////////////////////////////////
//////ACTUALIZAR PANTALLA
/////////////////////////////////////////////////////////////////////////////////////////////
printf("puntos %d", puntos);
SDL_BlitSurface(fondo, NULL, screen, NULL);
actualizar_imagen_balas(balas, screen, bala);
SDL_BlitSurface(puntosLetras, NULL, screen, &rectPuntosLetras);
sprintf(buffer, "%d", puntos);
puntosNumeros = TTF_RenderText_Blended(fuentePuntos, buffer, colorFuente);
SDL_BlitSurface(puntosNumeros, NULL, screen, &rectPuntosNumeros);
SDL_BlitSurface(enemigo1.cara[enemigo1.caraActual], NULL, screen, &enemigo1.rect);
SDL_BlitSurface(mirilla, NULL, screen, &rectMirilla);
SDL_Flip(screen);
////////////////////////////////////////////////////////////////
///GAME OVER
///////////////////////////////////////////////////////////////
if(balas == 0) //SI NO HAY BALAS, FIN DEL JUEGO
{
Mix_PlayChannel(-1, doh, 0);
while(true)
{
SDL_PollEvent(&evento); //comprobar eventos
SDL_GetMouseState(&ratonx, &ratony); //Pasar posicion raton
//SALIR?
//Si se pulsa el boton si, se sale del juego
if(evento.type == SDL_MOUSEBUTTONDOWN && ratonx >= rectBotonNo.x && ratony >= rectBotonNo.y && ratonx <= (rectBotonNo.x + rectBotonNo.w) && ratony <= (rectBotonNo.y + rectBotonNo.h) )
{
done = true;
break;
}
//Si se pulsa el boton no, vuelve a empezar, por tanto hay que reiniciar las variables
if(evento.type == SDL_MOUSEBUTTONDOWN && ratonx >= rectBotonSi.x && ratony >= rectBotonSi.y && ratonx <= (rectBotonSi.x + rectBotonSi.w) && ratony <= (rectBotonSi.y + rectBotonSi.h) )
{
puntos = 0;
balas = 11;
enemigo1.rect.x = 0; //Posicion anemigo
enemigo1.rect.y = 200;
enemigo1.hp = 100;
enemigo1.velocidad = 4;
//LIMPIAR LA ULTIMA CARA
switch(enemigo1.caraActual) //En el array caraLimpia se almacena le imagen sin sangre de cada cara
{
case 0:
SDL_BlitSurface(enemigo1.caraLimpia[0], NULL, enemigo1.cara[0], NULL); //Si pasamos a cara[1], renovamos la cara[0]
break;
case 1:
SDL_BlitSurface(enemigo1.caraLimpia[1], NULL, enemigo1.cara[1], NULL); //Si pasamos a cara[2], renovamos la cara[1]
break;
case 2:
SDL_BlitSurface(enemigo1.caraLimpia[2], NULL, enemigo1.cara[2], NULL); //Si pasamos a cara[3], renovamos la cara[2]
break;
case 3:
SDL_BlitSurface(enemigo1.caraLimpia[3], NULL, enemigo1.cara[3], NULL); //Si volvemos a la cara[0](vease mas abajo) renovamos la cara [3]
break;
}
enemigo1.caraActual = 0;
fondo = IMG_Load("fondo.png");
comprovar_surface(fondo);
done = false;
evento.type = SDL_NOEVENT; //Limpiar Buffer eventos
break;
}
enemigo1.mover(enemigo1.velocidad, &direccion); //Cambiar posicion del enemigo
SDL_BlitSurface(fondo, NULL, screen, NULL);
actualizar_imagen_balas(balas, screen, bala);
SDL_BlitSurface(puntosLetras, NULL, screen, &rectPuntosLetras);
SDL_BlitSurface(puntosNumeros, NULL, screen, &rectPuntosNumeros);
SDL_BlitSurface(enemigo1.cara[enemigo1.caraActual], NULL, screen, &enemigo1.rect);
SDL_BlitSurface(gameover, NULL, screen, &rectGameover);
SDL_BlitSurface(otraVez, NULL, screen, &rectOtraVez);
SDL_BlitSurface(botonSi, NULL, screen, &rectBotonSi);
SDL_BlitSurface(botonNo, NULL, screen, &rectBotonNo);
SDL_Flip(screen);
}
}
}
return 0;
}
void comprovar_surface(SDL_Surface * superficie)
{
if(!superficie) //Si despues de intentar cargar una imagen, la superficie esta vacia, algo va mal
{
SDL_Surface * screen = SDL_SetVideoMode(100, 100, 32, SDL_HWSURFACE); //Reinicio la ventana principal para quitar el fullscreen
printf("Error: %s", SDL_GetError());
getch();
exit(1);
}
}
void actualizar_imagen_balas(int balas, SDL_Surface * screen, SDL_Surface * bala)
{
SDL_Rect rect; //Rectangulo para la posicion de cada bala
rect.x = 770;
rect.y = 530;
switch(balas) //SE dibujan en la pantalla (screen) las balas restantes
{
case 1:
SDL_BlitSurface(bala, NULL, screen, &rect);
break;
case 2:
for(int i = 2; i > 0; i--)
{
SDL_BlitSurface(bala, NULL, screen, &rect);
rect.x -= 21;
}
break;
case 3:
for(int i = 3; i > 0; i--)
{
SDL_BlitSurface(bala, NULL, screen, &rect);
rect.x -= 21;
}
break;
case 4:
for(int i = 4; i > 0; i--)
{
SDL_BlitSurface(bala, NULL, screen, &rect);
rect.x -= 21;
}
break;
case 5:
for(int i = 5; i > 0; i--)
{
SDL_BlitSurface(bala, NULL, screen, &rect);
rect.x -= 21;
}
break;
case 6:
for(int i = 6; i > 0; i--)
{
SDL_BlitSurface(bala, NULL, screen, &rect);
rect.x -= 21;
}
break;
case 7:
for(int i = 7; i > 0; i--)
{
SDL_BlitSurface(bala, NULL, screen, &rect);
rect.x -= 21;
}
break;
case 8:
for(int i = 8; i > 0; i--)
{
SDL_BlitSurface(bala, NULL, screen, &rect);
rect.x -= 21;
}
break;
case 9:
for(int i = 9; i > 0; i--)
{
SDL_BlitSurface(bala, NULL, screen, &rect);
rect.x -= 21;
}
break;
case 10:
for(int i = 10; i > 0; i--)
{
SDL_BlitSurface(bala, NULL, screen, &rect);
rect.x -= 21;
}
break;
case 11:
for(int i = 11; i > 0; i--)
{
SDL_BlitSurface(bala, NULL, screen, &rect);
rect.x -= 21;
}
break;
}
}
void enemigo::mover(int velocidad, int *direccion)
{
//////////////////////////////////////////////////////////////////////////////////////////
////VERIFICAR SI EL ENEMIGO HA TOCADO UNA PARED PARA CAMBIAR LA POSICION A LA QUE MOVERSE
//////////////////////////////////////////////////////////////////////////////////////////
if(rect.x <= 0 && (rect.y != 0 && rect.y != 600) ) //Si el enemigo toca la pared de la IZQUIERDA
{
*direccion = (rand() % 8)+1;
//Verificamos que no salga una direccion que saque al enemigo de la pantalla
while(*direccion == 4 || *direccion == 7 || *direccion == 8)
{
*direccion = (rand() % 8)+1;
}
}
else if(rect.x >= 800 && (rect.y != 0 && rect.y != 600) ) //Si el enemigo toca la pared de la DERECHA
{
*direccion = (rand() % 8)+1;
//Verificamos que no salga una direccion que saque al enemigo de la pantalla
while(*direccion == 3 || *direccion == 5 || *direccion == 6 || *direccion == 2 || *direccion == 1)
{
*direccion = (rand() % 8)+1;
}
}
else if(rect.y <= 0 && (rect.x != 0 && rect.x != 800) ) //Si el enemigo toca la pared de ARRIBA
{
*direccion = (rand() % 8)+1;
//Verificamos que no salga una direccion que saque al enemigo de la pantalla
while(*direccion == 1 || *direccion == 5 || *direccion == 8)
{
*direccion = (rand() % 8)+1;
}
}
else if(rect.y >= 600 && (rect.x != 0 && rect.x != 800) ) //Si el enemigo toca la pared de ABAJO
{
*direccion = (rand() % 8)+1;
//Verificamos que no salga una direccion que saque al enemigo de la pantalla
while(*direccion == 2 || *direccion == 6 || *direccion == 7 || *direccion == 4 || *direccion == 3)
{
*direccion = (rand() % 8)+1;
}
}
else if(rect.x == 0 && rect.y == 0) //Si el enemigo esta en la esquina de ARRIBA IZQUIERDA
{
*direccion = (rand() % 8)+1;
//Verificamos que no salga una direccion que saque al enemigo de la pantalla
while(*direccion == 1 || *direccion == 4 || *direccion == 8)
{
*direccion = (rand() % 8)+1;
}
}
else if(rect.x == 0 && rect.y == 600) //Si el enemigo esta en la esquina de ABAJO IZQUIERDA
{
*direccion = (rand() % 8)+1;
//Verificamos que no salga una direccion que saque al enemigo de la pantalla
while(*direccion == 2 || *direccion == 4 || *direccion == 7)
{
*direccion = (rand() % 8)+1;
}
}
else if(rect.x == 800 && rect.y == 600) //Si el enemigo esta en la esquina de ABAJO DERECHA
{
*direccion = (rand() % 8)+1;
//Verificamos que no salga una direccion que saque al enemigo de la pantalla
while(*direccion == 2 || *direccion == 6 || *direccion == 3)
{
*direccion = (rand() % 8)+1;
}
}
else if(rect.x == 800 && rect.y == 0) //Si el enemigo esta en la esquina de ARRIBA DERECHA
{
*direccion = (rand() % 8)+1;
//Verificamos que no salga una direccion que saque al enemigo de la pantalla
while(*direccion == 1 || *direccion == 5 || *direccion == 3)
{
*direccion = (rand() % 8)+1;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
///ACTUALIZAR COORDENADAS DEL ENEMIGO SEGUN LA DIRECCION A LA QUE HALLA DE MOVERSE
//////////////////////////////////////////////////////////////////////////////////////////////
switch(*direccion)
{
case 1:
rect.y -= velocidad; //Arriba
break;
case 2:
rect.y += velocidad; //Abajo
break;
case 3:
rect.x -= velocidad; //Derecha
break;
case 4:
rect.x += velocidad; //Izquierda
break;
case 5:
rect.y -= velocidad; //Arriba/Derecha
rect.x += velocidad;
break;
case 6:
rect.y += velocidad; //Derecha/abajo
rect.x += velocidad;
break;
case 7:
rect.y += velocidad; //Abajo/izquierda
rect.x -= velocidad;
break;
case 8:
rect.y -= velocidad; //Izquieda/arriba
rect.x -= velocidad;
default:
break;
}
}
Musica:
http://www.playonloop.com
Eso es todo, espero que os guste

Edit: Aprovecho para preguntar como puedo hacer para quitar la pantallita de msdos, que sigue por ahi detras incordiando.