/* This source code copyrighted by JailDesigner (2020) started on Castalla 15-07-2020. Using some sample source code from Lazy Foo' Productions */ /*Descripción del enfoque utilizado para crear el juego. El programa contine una serie de clases/objetos básicos: la clase sprite permite dibujar partes de un fichero png en pantalla. La clase spriteanimated contiene funcionalidad adicional para crear animaciones. La clase text permite dibujar letras de un png en pantalla a partir de una cadena de texto. La clase menu permite crear una estructura con diferentes elementos, escribirlos en pantalla y seleccionar uno de ellos. A continuación tenemos las clases enfocadas a la lógica del juego, la clase player contiene la información del jugador, la clase balloon la de los enemigos y la clase bullet para las balas que dispara el jugador. La clase background es muy simple y sirve para pintar el fondo de la pantalla. Por ultimo, la clase gamedirector es la que realiza toda la lógica y se encarga de hacer interactuar al resto de objetos entre si. El objeto gamedirector tiene tres estados: titulo, juego y pausa. Segun su estado el bucle que recorre es distinto. En el bucle juego, el objeto gamedirector tiene un objeto jugador, un vector con los objetos globo y un vector con los objetos bala. Se encarga de comprobar las entradas de teclado o gamepad para cerrar la aplicacion, saltar al estado de pausa y para mover al jugador. Recorre el vector de globos y de balas y si tienen algun tipo asignado las gestiona. Comprueba las colisiones entre los globos y el jugador y entre las balas y los globos. Tiene ademas un nivel de amenaza que calcula en funcion del numero de globos en pantalla y que se va incrementando conforme aumenta la puntuación del jugador. Los objetos globo tienen varios contadores para alternar de un estado a otro. En los vectores que contienen objetos, se considera activos los objetos que tienen un tipo asociado diferente a NO_KIND */ #define TEST_ #include #include #include #include "background.h" #include "balloon.h" #include "bullet.h" #include "const.h" #include "gamedirector.h" #include "globals.h" #include "ltexture.h" #include "menu.h" #include "player.h" #include "sprite.h" #include "spriteanimated.h" #include "struct.h" #include "text.h" #include #include #include //Arranca SDL y crea la ventana bool init(); //Carga todos los recursos bool loadMedia(); //Libera todos los recursos y cierra SDL void close(); //Arranca SDL y crea la ventana bool init() { //Indicador de inicialización bool success = true; //Inicializa SDL if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO) < 0) { printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError()); success = false; } else { //Establece el filtro de la textura a nearest if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0")) { printf("Warning: Nearest texture filtering not enabled!"); } //Inicializa SDL_mixer if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) { printf("SDL_mixer could not initialize! SDL_mixer Error: %s\n", Mix_GetError()); success = false; } //Comprueba los mandos if (SDL_NumJoysticks() < 1) { printf("Warning: No joysticks connected!\n"); } else { //Carga el mando gGameController = SDL_JoystickOpen(0); if (gGameController == NULL) { printf("Warning: Unable to open game controller! SDL Error: %s\n", SDL_GetError()); } printf("%i joysticks were found.\n", SDL_NumJoysticks()); std::cout << SDL_JoystickNumButtons(gGameController) << " buttons\n"; } //Crea la ventana gWindow = SDL_CreateWindow("Super Popping (Like Loc) in Jailers World", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, VIEW_WIDTH, VIEW_HEIGHT, SDL_WINDOW_SHOWN); if (gWindow == NULL) { printf("Window could not be created! SDL Error: %s\n", SDL_GetError()); success = false; } else { //Crea un renderizador para la ventana con vsync gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (gRenderer == NULL) { printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError()); success = false; } else { //Inicializa el color de renderizado SDL_SetRenderDrawColor(gRenderer, 0x00, 0x00, 0x00, 0xFF); //Establece el tamaño del buffer de renderizado SDL_RenderSetLogicalSize(gRenderer, SCREEN_WIDTH, SCREEN_HEIGHT); //Inicializa el cargador de PNG int imgFlags = IMG_INIT_PNG; if (!(IMG_Init(imgFlags) & imgFlags)) { printf("SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError()); success = false; } } } } return success; } //Carga todos los recursos bool loadMedia() { //Indicador de éxito en la carga bool success = true; //Carga los gráficos del jugador if (!gPlayerTexture.loadFromFile("media/gfx/player.png")) { printf("Failed to load player texture!\n"); success = false; } //Carga los gráficos de los globos if (!gBalloonTexture.loadFromFile("media/gfx/balloon.png")) { printf("Failed to load balloon texture!\n"); success = false; } //Carga los gráficos de las balas if (!gBulletTexture.loadFromFile("media/gfx/bullet.png")) { printf("Failed to load bullet texture!\n"); success = false; } //Carga los gráficos del fondo del juego if (!gGameBackgroundTexture.loadFromFile("media/gfx/background.png")) { printf("Failed to load game background texture!\n"); success = false; } //Carga los gráficos del fondo de la pantalla de titulo if (!gTitleBackgroundTexture.loadFromFile("media/gfx/title.png")) { printf("Failed to load title texture!\n"); success = false; } //Carga varios gráficos para varios propósitos if (!gMiscTexture.loadFromFile("media/gfx/misc.png")) { printf("Failed to load misc texture!\n"); success = false; } //Carga los gráficos para el menu if (!gMenuTexture.loadFromFile("media/gfx/menu.png")) { printf("Failed to load menu texture!\n"); success = false; } //Carga los gráficos para el texto blanco if (!gWhiteFontTexture.loadFromFile("media/gfx/white_font.png")) { printf("Failed to load white font texture!\n"); success = false; } //Carga los gráficos para el texto negro if (!gBlackFontTexture.loadFromFile("media/gfx/black_font.png")) { printf("Failed to load black font texture!\n"); success = false; } //Carga la música del titulo gTitleMusic = Mix_LoadMUS("media/music/title.ogg"); if (gTitleMusic == NULL) { printf("Failed to load title music! SDL_mixer Error: %s\n", Mix_GetError()); success = false; } //Carga la música del juego gPlayingMusic = Mix_LoadMUS("media/music/playing.ogg"); if (gPlayingMusic == NULL) { printf("Failed to load playing music! SDL_mixer Error: %s\n", Mix_GetError()); success = false; } //Carga los efectos de sonido para la explosión de los globos gPopBalloonFX = Mix_LoadWAV("media/sound/balloon.wav"); if (gPopBalloonFX == NULL) { printf("Failed to load balloon sound effect! SDL_mixer Error: %s\n", Mix_GetError()); success = false; } //Carga los efectos de sonido para los disparos del jugador gBulletFX = Mix_LoadWAV("media/sound/bullet.wav"); if (gBulletFX == NULL) { printf("Failed to load bullet sound effect! SDL_mixer Error: %s\n", Mix_GetError()); success = false; } return success; } //Libera todos los recursos y cierra SDL void close() { //Libera todas las imagenes gPlayerTexture.free(); gGameBackgroundTexture.free(); gTitleBackgroundTexture.free(); gWhiteFontTexture.free(); gBlackFontTexture.free(); gMenuTexture.free(); gBalloonTexture.free(); gMiscTexture.free(); //Libera los efectos de sonido Mix_FreeChunk(gPopBalloonFX); Mix_FreeChunk(gBulletFX); gPopBalloonFX = NULL; gBulletFX = NULL; //Libra la música Mix_FreeMusic(gTitleMusic); gTitleMusic = NULL; Mix_FreeMusic(gPlayingMusic); gPlayingMusic = NULL; //Libera el mando SDL_JoystickClose(gGameController); gGameController = NULL; //Destruye la ventana SDL_DestroyRenderer(gRenderer); SDL_DestroyWindow(gWindow); gWindow = NULL; gRenderer = NULL; //Sal del subsistema SDL IMG_Quit(); SDL_Quit(); } int main(int argc, char *args[]) { //Arranca SDL y crea la ventana if (!init()) { printf("Failed to initialize!\n"); return -1; } else { //Carga los recursos if (!loadMedia()) { printf("Failed to load media!\n"); } else { //Crea el objeto gameDirector GameDirector gameDirector; //Inicializa el objeto gameDirector gameDirector.init(); #ifdef TEST gameDirector.resetBalloons(); #endif //Mientras no se quiera salir del juego while (!(gameDirector.getGameStatus() == GAME_STATE_QUIT)) { switch (gameDirector.getGameStatus()) { case GAME_STATE_TITLE: gameDirector.runTitle(); break; case GAME_STATE_PLAYING: gameDirector.runGame(); break; case GAME_STATE_PAUSED: gameDirector.runPausedGame(); break; } } } //Libera todos los recursos y cierra SDL close(); return 0; } }