Agustin Gonzalez Blog

miércoles, 14 de diciembre de 2011

Juego en C++ y SDL


Estaba pensando con que tema comenzar mi Blog, así que "hojeando" entre los proyectos de la facultad, encontré un juego que hice ya algún tiempo basado en  C++ (orientado a objetos) y SDL (Simple DirectMedia Layer), en este caso utilizadas mediante un sistema de clases (DMCS++), de carácter GPL (General Public License), aportado por un profesor de dicha facultad, Rubén Calabuig, las cuales son de su autoría.

Como sabrán las SDL son multiplataforma, y funcionan tanto como para Windows como para Linux. Cabe aclarar que con esta librería solo podremos realizar juegos relativamente simples (sin pretender 3D, para lo cual existen otro tipo de librerías, pero no entraremos en ese tema).

Descripción Somera:
Básicamente, el juego, se basa en encontrar las coincidencias de dos Fichas, con un límite de tiempo, guardando el puntaje del usuario en caso de ser el “High Score”.

Para los que estén empezando, les recomiendo leer otros temas previos para la realización de un juego, ya que como bien dice el título, esto solo es una descripción somera, lo único que les digo, es que básicamente el juego es un ciclo infinito, hasta "que pase algo", en este caso, el main principal, constaría de unas pocas líneas “en forma de instrucciones”:

int main ( int argc, char* argv[] )
{
  //==========================================================
  //        PROTECCION NECESARIA ANTE CIERRE INESPERADO
  //--------------------------------------------------------
  atexit(SDL_Quit);  // Cierre de las SDL, ante cierre anormal.
  //==========================================================
//         DECLARACION DE VARIABLES Y OBJETOS
//----------------------------------------------------------
  ClsMenu  menu;    // Administra menu principal
  ClsJuego juego;   // Administra juego
  ClsAyuda ayuda;   // Administra la ayuda
  short    op=0;    // Opcion ingresada

//==========================================================
//        INICIO DE APLICACION
//------------------------------------------------------------------
  // El ciclo es terminado solo si el usuario elije la opcion "salir".
  do
  {
    // Se muestra el menu y se guarda la opcion ingresada
    op = menu.mostrar();

    if(op == 1)
    {
      // Se cargan ( o vuelven a cargarse) los elementos de juego.
      juego.constructor();

      // Se muestra juego.
      juego.loop();

      // Se eliminan todos los sprites del juego anterior
      juego.eliminar();
    }
    else if(op == 2)
    {
      ayuda.mostrar();
    }
  }
  while(op != 3);

  // Se vuelve a construir el juego, para que al descargar las imagenes el des-
  // tructor por defecto no tenga problemas al intentar liberar vectores "vacios".
  juego.constructor();
  return 0;
}

Internamente, observaremos que el juego, orientado a objetos, consta de las siguientes clases:

ClsAyuda:
La ayuda del juego, a su vez consta de las funciones y atributos:

  //----------------
  // ATRIBUTOS
  //----------------
  private:
    ClsVirtual fondo// Muestra un .bmp con la ayuda


  //----------------
  // METODOS
  //----------------
  public:
    //----------------
    // DE ACCION
    //----------------
    // Constructor
    ClsAyuda();

    //----------------
    // DE INFORMACION
    //----------------
    // Verifica si la opcion volver al Menu Principal fue presionada
    int obtenerOpcion();

    //----------------
    // DE RENDERIZADO
    //----------------
    // Muestra la ayuda
    void mostrar();

    // Actualiza el fotograma virtual y el monitor principal
    void renderizar();

ClsNucleo: 
Núcleo principal del juego, el cual contiene los métodos y atributos “indispensables” del mismo.

  //----------------
  // ATRIBUTOS
  //----------------
  private:
    // Estado ACTUAL de la Ficha
    // false -> Inactiva
    // true  -> Activa
    bool estado;

    char strParametro[50]; // String para elementos de tipo parametro.

  //----------------
  // METODOS
  //----------------
  public:
    //----------------
    // DE ACCION
    //----------------
    // Carga el directorio y nombre de la ficha
    void cargarFicha(char* , char*);

    // Gira la ficha a visible o no
    void girar();

    // Setea estado de la ficha
    void setEstado(int );

    //----------------
    // DE INFORMACION
    //----------------
    // Retorna el estado actual de la ficha
    bool ESTADO(){return estado;}

    //----------------
    // SOBRECARGAS
    //----------------
    bool operator==(ClsFicha &);


ClsJuego:
Heredada de ClsNucleo, se encuentran las funciones que “hacen” principalmente a la aplicación. Sus componentes son:

  //----------------
  // ATRIBUTOS
  //----------------
  private:

    //--------------------
    //  OBJETOS NECESARIOS
    //--------------------
    ClsVirtual fotograma;      // Administra fotograma virtual en memoria ram
    ClsFicha   vFichas[24];    // Vector de objetos (* Podria utilizarse tambien una matriz)
    ClsVirtual fondo;          // Administrador de fondo del juego.
    ClsTexto   texto;          // Administra modo texto
    ClsSprite  transFicha;     // Muestra "transparencia" cuando se selecciona una ficha
    clsAzar    random        // Usado para ubicar las fichas en juego

    //-----------------------------
    //    CRONOMETRADORES GENERALES
    //-----------------------------
    ClsTimer pausa           // Pausa al dar vuelta dos fichas. Se usa esta variable para que
                               // no influya en el cronometro de Juego.
    ClsTimer cronometroJUEGO;  // Cronometro de juego
    short    time_MIN        // Variable que muestra cronometro en minutos

    //--------------
    //  VARIABLES
    //--------------
    short vIndice[24];         // Vector de indices sobre el cual se ejecutara el azar
    short indice             // Indice general, para el manejo del vector de objetos
    char  strAux[50];          // Cadena de parametro auxiliar

    //--------------------------
    // CONTROLADORES DE PUNTAJE
    //--------------------------
    ClsPuntaje regaux;         // Registro auxiliar para guardar el registro de puntajes
    ClsPuntaje puntaje;        // Administra puntaje DURANTE el juego
    short aciertos           // Numero de aciertos seguidos usado por el multiplicador
    short puntMax            // Almacena el puntaje maximo guardado en disco
    char  puntMax_nombre[5];   // Almacena nombre del jugador con puntaje maximo

    //----------------
    // CONTADORES
    //----------------
    int contador             // Contador para ejecutar logica
    int cFichasTotales       // Cantidad de fichas actuales en juego

  //----------------
  // METODOS
  //----------------
  public:
    //----------------
    // DE ACCION
    //----------------
    // Contructor por defecto.
    ClsJuego();

    // "Constructor" para armar o rearmar el juego.
    void constructor();

    // Loop de juego principal
    void loop();

    // Ejecuta Azar
    void ejecutarAzar();

    // Carga las fichas de juego en el vector de obj.
    void cargarFichas();

    // Ejecuta Logica
    int ejecutarLogica(int int);

    // Obtiene indice de la ficha presionada
    int obtenerIndice();

    // Carga en una cadena el puntaje de juego
    void strPuntaje();

    // Controla y carga cronometro de juego en una cadena
    void strCronometro();

    // Libera vector de sprites
    void eliminar();
    //----------------
    // DE RENDERIZADO
    //----------------
    // Renderizador de pantalla
    void renderizar();

    // Ubicador de fichas en pantalla
    void ubicarFichas();

ClsMenu:
Muestra el Menú principal del juego

  //----------------
  // ATRIBUTOS
  //----------------
  private:
    ClsVirtual fondo;        // Administra fondo del menu principal
    ClsSprite  vOpciones[3]; // Vector de Sprite de opciones del MP
    short      opcion;       // Administrador indice de vector de opciones

  //----------------
  // METODOS
  //----------------
  public:
    //----------------
    // DE ACCION
    //----------------
    // Constructor por defecto
    ClsMenu();

    // Verifica que opcion fue seleccionada
    int obtenerOpcion();

    //----------------
    // DE RENDERIZADO
    //----------------
    // Encargado de actualizar en pantalla los Frames
    void renderizar();

    // Muestra el menu Principal
    int mostrar();

ClsPuntaje:
Consta de elementos necesarios para el manejo de puntaje

  //----------------
  // ATRIBUTOS
  //----------------
  private:
    //----------------
    // OBJETOS
    //----------------
    ClsVirtual fondo  // Administra fondo que se muestra en caso de lograrse algún
                        // puntaje máximo.
    ClsIngreso ingreso; // Administra ingreso del usuario.
    clsArchivo archivo; // Administra el archivo de puntajes.

    //----------------
    // VARIABLES
    //----------------
    char strParametro[50];  // Usado para parametros de tipo char.
    int  multiplicador    // Coeficiente por el cual se multiplica puntaje logrado.
    long puntaje;           // Puntaje de juego.
    char nombre[5];         // Nombre del usuario que logro el máximo puntaje.

  //----------------
  // METODOS
  //----------------
  public:
    //----------------
    // DE ACCION
    //----------------
    // Constructor.
    ClsPuntaje();

    // Resetea puntaje y multiplicador.
    void reset();

    // Calcula puntaje correspondiente.
    void controlar(int );

    // Setea el nombre.
    void setNombre(ClsMonitor&);

    //----------------
    // DE ESCRITURA
    //----------------
    // Guarda puntaje en disco.
    bool guardar(ClsPuntaje&, ClsMonitor&);

    // Comprueba si el puntaje es mayor al máximo.
    bool comprobarPuntaje(ClsPuntaje&);

    // Lee puntaje de disco.
    bool leer(ClsPuntaje&);

    //----------------
    // DE INFORMACION
    //----------------
    int   MULTIPLICADOR() {return multiplicador;}

    int   PUNTAJE(){return puntaje;}

    char *NOMBRE() {return nombre;}

 DMCS++:
La librería DMCS++, creada por Rubén Calabuig, es un sistema de clases el cual nos permitirá manejar las SDL mediante objetos, contando con los siguientes elementos:
ClsAudio: Administración de audio y sonidos.
ClsDirectMedia: Para administrar los elementos necesarios de los sistemas de Video, Audio, Timers, CD-ROM y Joystick.
ClsError: Contiene una definición de los errores producidos.
ClsEvento: Guarda los eventos producidos.
ClsImagen: Administración de imágenes.
ClsPantalla: Elementos para administrar las pantallas.
ClsPunto: Para leer y dibujar píxeles.
ClsSprite: Para administrar Sprites.
ClsTexto: Para administrar fuentes y textos, en modo gráfico.
ClsTimer: Para administrar Timers.
ClsArchivo: Para manipulación de Archivos.
ClsAzar y Random: Para manejar números aleatorios.

Como bien dije el proyecto está totalmente orientado a objetos, manejando sobrecargas, herencia, encapsulamiento, enumeraciones, etc, además, de estar documentado, para hacer más fácil su entendimiento.

Aclaro que quizás no sean las mejores técnicas utilizadas,  pero para quién ande buscando un ejemplo del tema, espero que le sirva.

IMPORTANTE!
Compilar con CodeBlocks
Es necesario tener "linqueadas" las SDL, de la siguiente manera (previamente bajadas):
1 - Copiar el contenido de las carpetas SDL-1.2.14-win32 Y SDL-devel-1.2.14-mingw32 a la carpeta CodeBlocks/MinGW, si pide reemplazar, seleccionamos “SI”.
2 - Una vez hecho esto abrir CodeBlocks, seleccionar "settings", "compiler and debugger", "linker settings" y en "other linkers opcions", copiar lo siguiente para enlazar las librerías:
-lmingw32  -lSDLmain  -lSDL  -lSDL_image  -lSDL_mixer  -lSDL_ttf

Cualquier consulta y crítica constructiva, será recibida, sin más que decir les dejo el Link de descarga: Clic Aquí
Subo el COMPILADO también, por si lo desean ejecutar directamente: Clic Aquí


Aclaración!!!: Notése que el Juego "compilado" no funciona debería ser. Bueno esto simplemente se debe a que lo compile (como verán en el Código Fuente), con una línea (un if en la función loop, para ser más precisos) comentada. Luego lo resubo corregido.