jueves, 11 de octubre de 2012

Space Invaders OpenGL (GLUT)


Space Invaders

Space invaders es un juego diseñado originalmente por Toshihiro Nishikado de Taito Corporation en el año 1978, que tuvo un gran éxito en el mercado, considerándoselo un clásico hasta el día de hoy, del cual se crearon versiones para distintas consolas y sistemas, pues curiosamente este no contaba con protección de copyright.

El juego se trata de eliminar oleadas de marcianos con un cañón el cual el jugador controla, antes de que estos lleguen a la “tierra”.
En el juego aleatoriamente y con una cantidad de puntaje indefinida aparece una nave extraterrestre de color rojo que proporciona al jugador, si este logra destruirla una cantidad aleatoria de puntaje, ademas en la pantalla de juego hay lo que parecen ser 4 bunkers que “ayudan” a defender la tierra.

En la versión creada en esta ocasión, hay algunas diferencias que por razones de tiempo no termine de programar, aunque en su esencia, se puede aprecia del juego su lógica y estética.

No ha sido fácil “emular” la estética del juego, puesto que encontrar los sprites originales en la web, a sido un trabajo muy duro, puesto que la cantidad de imitaciones del juego es basta, asi en el proceso de desarrollo, se obtuvieron resultados hasta llegar a tener una lo mas parecido al “original”, o mas bien al que todos conocen.

Screen durante el desarrollo del juego

Para el desarrollo de la aplicación se ocuparos los sprites de la siguiente imagen como modelos, alcanzando una estética bastante similar.


Screen original del juego

Screen actual del desarrollo
Los elementos faltantes dentro del diseño aun se encentran en fase de implementación, por falta de tiempo, aunque en teoría estos no son de una gran complejidad, puesto que la parte lógica “gruesa” del diseño ya se encuentra programada y entendida en el código.

Para finalizar con la presentación de la aplicación una ultima imagen correspondiente a la pantalla de inicio del juego, espero que lo disfruten.

Screen vista actual
Descripción de funciones y archivos usados:

space_slpha.c: En este archivo se encuentra la linea general del juego, ademas de las funcionalidades de glut que apoyan el proceso, tales como el apoyo al teclado, el re dimensionamiento de objetos..
  • void IniciarGLUT(); esta es una función de propósito general no especifica para el juego, libera de código extra en la función main(); ya que se encarga de tareas especificas de glut que no necesariamente son tarea de la linea principal de un programa.
  • void PintarEscena(); esta función se encarga de exhibir todos lo objetos del juego y debe ser específicamente llamada por la función glutDisplayFunc(“PintarEscena”); de lo contrario no hará nada.
  • void ReProyectar(int w, int h); esta función se encarga de ajustar los tamaños si es que la ventana se redimensiona, ademas crea la escala con la que se trabajara en el resto del juego, los argumentos “w”, “h” usan como argumento el tamaño actual de la pantalla. Esta función debe ser llamada o enviada como argumento específicamente a la función glutReshapeFunc(ReProyectar); de lo contrario tampoco se hará nada.
  • void ControlTeclado(unsigned char key, int x, int y); fácil, esta función controla las teclas que no son especiales dentro del juego “ENTER” y “ESC” y debe ser argumentada para la función glutKeyboardFunc(ControlTeclado); y sus argumentos propios son un “key” correspondiente a una tecla y un “x” , “y” que aunque en mi caso particular no ocupo debe ser igualmente anexado.
  • void ControlFlechas(int key, int x, int y); igualmente fácil, esta función se encarga de los eventos que ocurren con la flechas del teclado, puesto a que estas son teclas especiales, no se consideran dentro de la funcion descrita anteriormente por tanto son argumentadas a glutSpecialFunc(ControlFlechas); y también cuentan entra sus argumentos un “key” que es la flecha oprimida, y un “x”, “y” que no utilizo.


space_alpha.h: En este archivo se concentran las acciones propias del juego y no la funcionalidades de glut como por ejemplo la pantalla de juego, la pantalla principal y la acción de disparar, ademas de la variables globales que apoyan los cálculos y conjunto de flags que permiten las acciones

  • void cargar_variables(); esta función se encarga de establecer los valores iniciales (si es que se necesita) de la mayoría de la variables globales del juego.
  • void disparo(); se encarga de la acción de disparo cuando el usuario ataca.
  • void pantalla_de_juego(); pantalla de juego, básicamente el alma del juego, posiciona enemigos y jugador en la pantalla aparte de hacer los cálculos de rectángulos mínimos que se necesitan para detectar las colisiones, (el calculo del choque directo entre jugador y extraterrestre no se encuentra hecho aunque si se detecta si un disparo destruye a un enemigo(es efectivamente destruido)).
  • void presentación(); simple y estética, es la pantalla de “bienvenida al juego”, cabe señalar que si se esta un tiempo mirando la pantalla la nave roja o “UFO” escapara de la vista del usuario (efecto de una animación programada no una torpeza).
  • void Avanzar(int x); función recursiva que se encarga del manejo de contadores y posiciones necesarias para la correcta ejecución del juego aparte de dar continuidad en caso de que el usuario no intervenga “jugando”

space_sprites.h: aquí se encuentra la parte artística de todo este asunto, este archivo contiene el conjunto de sprites en matrices, y las respectivas funciones que manejan dichas matrices, básicamente todas la funciones hacen lo mismo pero al ser diferentes los tamaños de cada objeto no me propuse el crear una función genérica para todos los sprites, aunque si agrupe los de características similares.
  • void ubicar_sprite(int sprite, float six, float siy, float tam_pix); pone enemigos y jugador en pantalla “sprite”, es el subindice correspondiente al sprite deseado:
0 - “CALAMAR”
1 - “CANGREJO”
2 - “PULPO”
3 - “UFO”
4 - “NAVE”

Las variables “six”, “siy”, son posiciones eje coordenados para los objetos, y “tam_pix” define el tamaño del pixel usado para imprimir el objeto.

  • void simbolo(int sprite, float six, float siy); similar al anterior, pero imprime símbolos definidos en la matriz que maneja, no define tamaño de pixel:

0 - “?”
1 - “!”
2 - “=”

  • void say_space(float six, float siy); pone la palabra space en pantalla en la posición (six, siy);
  • void say_invaders(float six, float siy); pone la palabra invaders en pantalla en la posición (six, siy);
  • void say_pts(float six, float siy); pone la sigla pts. en pantalla en la posición (six, siy);
  • void numero(int num, float six, float siy); función similar al a ubicar sprite pero esta imprime números en pantalla donde, “num” es el numero a imprimir.
  • void bala(float six, float siy); pone el disparo en pantalla cuando se dispara;
  • void mostrar_text(char cadena[], float x, float y); imprime texto sin sprite donde “cadena[]” es el texto a imprimir, y (“x”, “y”) la posición.



    Enlace descarga código fuente: Space_invaders.rar








lunes, 8 de octubre de 2012

Ejemplo Simple OpenGL/glut

No acabo de encontrar un ejemplo de OpenGL que sea lo suficientemente simple y completo como para partir de una base cada vez que empiezo a escribir algún demo.
Me ahorre las explicaciones teóricas y entre otras cosas el siguiente código aplica, uso de teclado y sus funciones especiales, rotaciones controladas por teclado del plano general, rotaciones y traslaciones de los objetos en si (las cuales también pueden ser activadas o desactivadas por teclado) ademas del uso de objetos 3D.

Bueno, no es la gran cosa pero aquí esta, las teclas de función y sus respectivos usos están en los comentarios del código:

Enlace código: soltierraluna.c

Y aquí dejo un video demostracion: