martes, 19 de julio de 2011

GameEngine: Capitulo 23. Bullet Manager

Hola a todos,

Bienvenidos a un nuevo capitulo de como crear tu propio game engine.

El capitulo de hoy es discutible que tuviera que ir en el game engine, para más de uno deberia estar en código de juego, pero, es tal su aparición en la mayoria de juegos 2D que , personalmente, no lo he considerado una mala opción incluirlo en el engine

El tema de hoy es el bullet manager, dicho de otra manera, un gestionador de objetos que se mueven por pantalla, disparados por algún ente del juego y que desaparecen al chocar contra una pared.

Poco hay que decir respecto al código: una función para resetar todas las balas, una para mostrarlas y otra para disparar, creo que el código es el que mejor puede explicar como funciona (tranquilos que son muy pocas lineas):

BulletManager.cpp (el . h es trivial, si lo quereis ver está en el megaupload)

/**************************************************************************************************/
// Código creado por F.Bordas (LordPakus) como ejemplo de creación de un game engine
// para el blog LordPakus (http://lordpakus.blogspot.com/).
// Prohibida la distribución fuera de este blog sin el permiso expreso del autor
/**************************************************************************************************/

/**************************************************************************************************/
// BulletManager.cpp : Código de la parte de disparos del game engine
// Caracteristicas especiales: Esta clase implementa un singleton, es decir, solo podrá existir un objeto de esta clase en todo el proyecto
/**************************************************************************************************/
#include "BulletManager.h"
#include "MyGL.h"
#include "Core.h"
#include <iostream> //Usada para imprimir por consola

using namespace std;

#include <math.h> //Funciones de matematicas.

#define PI 3.14159265

//Instancia única del bullet manager
BulletManager BulletManager::instance;

BulletManager::BulletManager()
{
}

BulletManager::~BulletManager()
{
}

//Devolvemos el puntero al singleton
BulletManager& BulletManager::singleton()
{
return instance;
}

void BulletManager::Init()
{
int i;

for(i = 0 ; i< MAX_BULLETS ; i++)
bullet_array[i].active = false;
}

void BulletManager::Shoot(int x, int y, int angle, int vel,char graf[],int part,char sound[])
{
int i;

for( i = 0 ; i < MAX_BULLETS; ++i )
{
//Si esa bala no está activada, la activamos
if(bullet_array[i].active == false )
{
cout << "Disparamos bala : " << x << " " << y << " " << angle << " " << vel << " " << graf << " " << part << " " << sound << "\n";

//Seteamos los gráficos de la bala
bullet_array[i].active = true;
bullet_array[i].x = x;
bullet_array[i].y = y;
bullet_array[i].vx = vel*cos( (angle*PI)/180 );
bullet_array[i].vy = vel*sin( (angle*PI)/180 );
sprintf( bullet_array[i].cad , graf );
bullet_array[i].part = part;
//Hacemos sonar el disparo
LPE.PlaySound(sound);
break;
}
}
}


void BulletManager::Draw()
{
int i;

for( i = 0 ; i < MAX_BULLETS; ++i )
{
//Si la bala está activada
if(bullet_array[i].active == true )
{
//Pintamos
LPE.DrawSprite(bullet_array[i].x, bullet_array[i].y, bullet_array[i].cad, bullet_array[i].part );

//Movimiento
bullet_array[i].x += bullet_array[i].vx;
bullet_array[i].y += bullet_array[i].vy;

//Colisión con las tiles
if ( LPE.CollideGraphWithMap2D( bullet_array[i].x , bullet_array[i].y ,bullet_array[i].cad , bullet_array[i].part ) )
{
//Si colisiona con las tiles, la eliminamos.
bullet_array[i].active = false;
}
}
}
}

Y el código del juego se modifica muy ligeramente:
Por un lado en el inicio del estado:
void enter()
{
LPE.LoadTileMap("Data\\Levels\\level08.txt");
BulletManager::singleton().Init();
}


Por otro lado en la parte de pintado, al inicio:

LPE.DrawMap2D(); //Pintamos el mapa cargado
BulletManager::singleton().Draw();
LPE.Scroll(xplayer,yplayer);

Y finalmente decidimos cuando disparar:
if ( LPE.MouseClick() )
{
if(right)
BulletManager::singleton().Shoot(xplayer+10 , yplayer-15 , angle,40,"PLAYER",8,"DISPARO");
else
BulletManager::singleton().Shoot(xplayer-60 , yplayer-15 , angle,40,"PLAYER",8,"DISPARO");
}


Aquí os dejo el video como os debería quedar el bullet manager:



Espero que os lo hayáis pasado bien y hayáis aprendido. Para dudas y sugerencias ya sabeis donde estoy.

LordPakusBlog
Nos vemos

0 comentarios :

Publicar un comentario

Entradas populares