lunes, 11 de julio de 2011

GameEngine: Capitulo 18.Mejorando el Graphics2DManager (IV)

Hola a todos,

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

El capitulo de hoy tratará sobre la mejora del Graphics2DManager al aplicarle rotaciones e inversiones en el eje x. Las rotaciones son muy usadas en la mayoria de juegos 2D (para orientar a un personaje, una nave, apuntar con un arma...) y las inversiones permiten reaprovechar mejor los gráficos al no tener que tener N versiones de un mismo gráfico flipeado en las diferentes dimensiones del espacio.

En el caso concreto del ejemplo que os mostraré, las rotaciones las uso para orientar el arma del personaje con el ratón y el flip en x para que se oriente dicho personaje a la izquierda o a la derecha.

El código que se ha tocado abarca todo el proyeto (como siempre a estas alturas del desarrollo) pero la parte principal se encuentra en la función de pintado 2D:

void Graphics2DManager::Draw(float Xi, float Yi, float Xf, float Yf,float xi, float yi, float xf, float yf,char cad[], bool invx , float angle)
{
float temp;
TextureManager::singleton().Texture(cad); //Usamos la textura
//Si tenemos que rotar, rotamos.
if( angle != 0 )
{
//Si tenemos que invertir, invertimos
if ( invx )
{
//angle += 180;
temp = Yf;
Yf = Yi;
Yi = temp;
}

glPushMatrix();
glLoadIdentity();
glTranslatef( xi + (xf - xi)/2, yi + (yf - yi)/2 , 0);
glRotatef(angle,0,0,1);
glBegin(GL_QUADS);
glTexCoord2f( Xf, Yi); glVertex2i( (xf - xi)/2 , (yf - yi)/2 ); // Top Right Of The Quad (Front)
glTexCoord2f( Xi, Yi); glVertex2i( -(xf - xi)/2 , (yf - yi)/2 ); // Top Left Of The Quad (Front)
glTexCoord2f( Xi, Yf); glVertex2i( -(xf - xi)/2 , -(yf - yi)/2 ); // Bottom Left Of The Quad (Front)
glTexCoord2f( Xf, Yf); glVertex2i( (xf - xi)/2 , -(yf - yi)/2 ); // Bottom Right Of The Quad (Front)
glEnd();
glPopMatrix();
}
else
{
//Si tenemos que invertir, invertimos
if ( invx )
{
temp = Xf;
Xf = Xi;
Xi = temp;

temp = xf-xi;
xi += temp;
xf += temp;
}

glBegin(GL_QUADS);
glTexCoord2f( Xf, Yi); glVertex2i( xf , yf ); // Top Right Of The Quad (Front)
glTexCoord2f( Xi, Yi); glVertex2i( xi , yf ); // Top Left Of The Quad (Front)
glTexCoord2f( Xi, Yf); glVertex2i( xi , yi ); // Bottom Left Of The Quad (Front)
glTexCoord2f( Xf, Yf); glVertex2i( xf , yi ); // Bottom Right Of The Quad (Front)
glEnd();
}
}

El código empieza a complicarse un poco, si teneis dudas del por que he hecho alguna cosa no dudeis en preguntar.

Aparte de esto, el código en el juego es ridiculo comparado con los resultados:
void draw ()
{
static bool right = true;
static int angle = 0;
int x,y;

if ( LPE.KeyBoardRight() )
right = true;

if ( LPE.KeyBoardLeft() )
right = false;

if ( right )
LPE.DisableFlag("INVX");
else
LPE.EnableFlag("INVX");
//Personaje
LPE.DrawAnim(300,260,"RUN");
//Pintamos el arma
LPE.GetMousePosition(&x,&y);
angle = atan2( (double)(y - 230), (double)( 290 - x) ) * 180/PI + 180;
angle %= 360;

if(right)
LPE.DrawCenterRotate(290,230,angle,"PLAYER",3);
else
LPE.DrawCenterRotate(240,230,angle,"PLAYER",3);

//Cuando hemos acabado de pintar lo que queremos tener girado, desactivamos los flips de x
LPE.DisableFlag("INVX");

//Pintado de textos
LPE.DrawText("SYSTEM",200,350,"ANIMACIONES 2D");
}

Las funciones EnableFlag y DisableFlag me las he sacado de la manga inspirandome en la filosofia de OpenGL de flags. En este caso concreto, ahora por ahora, solo sirven para activar la inversión del pintado en X de forma que mientras el flag “INVX” esté activo todo lo que se pinte estará invertido en x. De esta manera no hacen falta más funciones para pintar de diferentes maneras y permite que se introduzcan cientos de nuevos flags que permitan nuevos tratamientos de la imagen (shaders, blendings,etc...)

La función de rotación la he hecho aparte (DrawCenterRotate) ya que las coordenadas que se le pasan son centradas y no referentes a una esquina de la imagen. El motivo por el cual giro respecto al centro es por que en la mayoria de juegos las rotaciones solo tienen sentido respecto al centro.

Para ver el resultado le podeis echar un ojo al video donde vereis que la rotación y el flipeo van extremadamente fluidos:


El código y el ejecutable de ejemplo lo podeis encontrar como siempre en la carpeta de descargas 

Espero que os lo hayais pasado tan bien como yo y que tengais ganas de ver el siguiente capitulo : el gestor de tiles.

LordPakusBlog
Nos vemos

2 comentarios :

  1. Hola Pako, solo un comentario la verdad no se como corregirlo solo tengo la idea, cuando el personaje se mueve en el sentido contrario del puntero el arma queda de cabeza, de mas esta decir que esto no es normal, lo ideal seria que el player se moviera caminando de espaldas siempre mirando el puntero

    ResponderEliminar
  2. Pues te vas a reir, pero tienes toda la razón. No habia ni caido en la posibilidad de caminar hacia atrás...

    Me lo miro a ver si lo puedo arreglar rápido y subir
    los cambios

    Muchisimas gracias por tu aportación, es un detallito que hace que se gane mucho en calidad final .

    Nos vemos

    ResponderEliminar

Entradas populares