diff --git a/source/const.h b/source/const.h index ef413d2..cbd8d50 100644 --- a/source/const.h +++ b/source/const.h @@ -58,8 +58,7 @@ const int GAMECANVAS_THIRD_QUARTER_Y = (GAMECANVAS_HEIGHT / 4) * 3; #define SUBSECTION_GAME_GAMEOVER 3 #define SUBSECTION_TITLE_1 3 #define SUBSECTION_TITLE_2 4 -#define SUBSECTION_TITLE_3 5 -#define SUBSECTION_TITLE_INSTRUCTIONS 6 +#define SUBSECTION_TITLE_INSTRUCTIONS 5 // Ningun tipo #define NO_KIND 0 diff --git a/source/game_logo.cpp b/source/game_logo.cpp new file mode 100644 index 0000000..cbc7463 --- /dev/null +++ b/source/game_logo.cpp @@ -0,0 +1,209 @@ +#include "game_logo.h" + +// Constructor +GameLogo::GameLogo(SDL_Renderer *renderer, Screen *screen, Asset *asset, int x, int y) +{ + // Copia los punteros + this->renderer = renderer; + this->screen = screen; + this->asset = asset; + this->x = x; + this->y = y; + + // Crea los objetos + dustTexture = new Texture(renderer, asset->get("title_dust.png")); + coffeeTexture = new Texture(renderer, asset->get("title_coffee.png")); + crisisTexture = new Texture(renderer, asset->get("title_crisis.png")); + + coffeeBitmap = new SmartSprite(coffeeTexture, renderer); + crisisBitmap = new SmartSprite(crisisTexture, renderer); + dustBitmapL = new AnimatedSprite(dustTexture, renderer, asset->get("title_dust.ani")); + dustBitmapR = new AnimatedSprite(dustTexture, renderer, asset->get("title_dust.ani")); + + // Sonidos + crashSound = JA_LoadSound(asset->get("title.wav").c_str()); + + // Inicializa las variables + init(); +} + +// Destructor +GameLogo::~GameLogo() +{ + dustTexture->unload(); + delete dustTexture; + + coffeeTexture->unload(); + delete coffeeTexture; + + crisisTexture->unload(); + delete crisisTexture; + + delete coffeeBitmap; + delete crisisBitmap; + delete dustBitmapL; + delete dustBitmapR; + + JA_DeleteSound(crashSound); +} + +// Inicializa las variables +void GameLogo::init() +{ + const int xp = x - coffeeBitmap->getWidth() / 2; + const int desp = getInitialVerticalDesp(); + // Variables + status = disabled; + shake.desp = 1; + shake.delay = 3; + shake.lenght = 8; + shake.remaining = shake.lenght; + shake.counter = shake.delay; + shake.origin = xp; + + // Inicializa el bitmap de 'Coffee' + coffeeBitmap->init(); + coffeeBitmap->setPosX(xp); + coffeeBitmap->setPosY(y - coffeeBitmap->getHeight() - desp); + coffeeBitmap->setWidth(167); + coffeeBitmap->setHeight(46); + coffeeBitmap->setVelX(0.0f); + coffeeBitmap->setVelY(2.5f); + coffeeBitmap->setAccelX(0.0f); + coffeeBitmap->setAccelY(0.1f); + coffeeBitmap->setSpriteClip(0, 0, 167, 46); + coffeeBitmap->setEnabled(true); + coffeeBitmap->setEnabledCounter(0); + coffeeBitmap->setDestX(xp); + coffeeBitmap->setDestY(y - coffeeBitmap->getHeight()); + + // Inicializa el bitmap de 'Crisis' + crisisBitmap->init(); + crisisBitmap->setPosX(xp + 15); + crisisBitmap->setPosY(y + desp); + crisisBitmap->setWidth(137); + crisisBitmap->setHeight(46); + crisisBitmap->setVelX(0.0f); + crisisBitmap->setVelY(-2.5f); + crisisBitmap->setAccelX(0.0f); + crisisBitmap->setAccelY(-0.1f); + crisisBitmap->setSpriteClip(0, 0, 137, 46); + crisisBitmap->setEnabled(true); + crisisBitmap->setEnabledCounter(0); + crisisBitmap->setDestX(xp + 15); + crisisBitmap->setDestY(y); + + // Inicializa el bitmap de 'DustRight' + dustBitmapR->resetAnimation(); + dustBitmapR->setPosX(coffeeBitmap->getPosX() + coffeeBitmap->getWidth()); + dustBitmapR->setPosY(y); + dustBitmapR->setWidth(16); + dustBitmapR->setHeight(16); + dustBitmapR->setFlip(SDL_FLIP_HORIZONTAL); + + // Inicializa el bitmap de 'DustLeft' + dustBitmapL->resetAnimation(); + dustBitmapL->setPosX(coffeeBitmap->getPosX() - 16); + dustBitmapL->setPosY(y); + dustBitmapL->setWidth(16); + dustBitmapL->setHeight(16); +} + +// Pinta la clase en pantalla +void GameLogo::render() +{ + // Dibuja el logo + coffeeBitmap->render(); + crisisBitmap->render(); + + // Dibuja el polvillo del logo + dustBitmapR->render(); + dustBitmapL->render(); +} + +// Actualiza la lógica de la clase +void GameLogo::update() +{ + if (status == moving) + { + coffeeBitmap->update(); + crisisBitmap->update(); + + // Si los objetos han llegado a su destino, cambiamos de Sección + if (coffeeBitmap->hasFinished() && crisisBitmap->hasFinished()) + { + status = shaking; + + // Pantallazo blanco + screen->setFlash({0xFF, 0xFF, 0xFF}, 5); + + // Reproduce el efecto sonoro + JA_PlaySound(crashSound); + } + } + + else if (status == shaking) + { + // Agita el logo + if (shake.remaining > 0) + { + if (shake.counter > 0) + { + shake.counter--; + } + else + { + shake.counter = shake.delay; + const int desp = shake.remaining % 2 == 0 ? shake.desp * (-1) : shake.desp; + coffeeBitmap->setPosX(shake.origin + desp); + crisisBitmap->setPosX(shake.origin + desp + 15); + shake.remaining--; + } + } + else + { + coffeeBitmap->setPosX(shake.origin); + crisisBitmap->setPosX(shake.origin + 15); + status = finished; + } + + dustBitmapR->update(); + dustBitmapL->update(); + } + + else if (status == finished) + { + dustBitmapR->update(); + dustBitmapL->update(); + } +} + +// Activa la clase +void GameLogo::enable() +{ + init(); + status = moving; +} + +// Indica si ha terminado la animación +bool GameLogo::hasFinished() +{ + return (status == finished); +} + +// Recarga las texturas +void GameLogo::reLoad() +{ + dustTexture->reLoad(); + coffeeTexture->reLoad(); + crisisTexture->reLoad(); +} + +// Calcula el desplazamiento vertical inicial +int GameLogo::getInitialVerticalDesp() +{ + int despUp = y; + int despDown = GAMECANVAS_HEIGHT - y; + + return std::max(despUp, despDown); +} \ No newline at end of file diff --git a/source/game_logo.h b/source/game_logo.h new file mode 100644 index 0000000..5870ff6 --- /dev/null +++ b/source/game_logo.h @@ -0,0 +1,84 @@ +#pragma once + +#include +#include "common/asset.h" +#include "common/screen.h" +#include "common/smartsprite.h" +#include "common/jail_audio.h" +#include "const.h" + +#ifndef GAME_LOGO_H +#define GAME_LOGO_H + +// Clase GameLogo +class GameLogo +{ +private: + // Objetos y punteros + SDL_Renderer *renderer; // El renderizador de la ventana + Screen *screen; // Objeto encargado de dibujar en pantalla + Asset *asset; // Objeto que gestiona todos los ficheros de recursos + + Texture *dustTexture; // Textura con los graficos del polvo + Texture *coffeeTexture; // Textura con los graficos de la palabra coffee + Texture *crisisTexture; // Textura con los graficos de la plabra crisis + + AnimatedSprite *dustBitmapL; // Sprite con la el polvo que aparece al colisionar el texto de la pantalla de titulo + AnimatedSprite *dustBitmapR; // Sprite con la el polvo que aparece al colisionar el texto de la pantalla de titulo + + SmartSprite *coffeeBitmap; // Sprite con la palabra COFFEE para la pantalla de titulo + SmartSprite *crisisBitmap; // Sprite con la palabra CRISIS para la pantalla de titulo + + // Variables + int x; // Posición donde ddibujar a la clase + int y; // Posición donde ddibujar a la clase + JA_Sound_t *crashSound; // Sonido con el impacto del título + + enum status_e + { + disabled, + moving, + shaking, + finished + } status; // Estado en el que se encuentra la clase + + struct shake_t + { + int desp; // Pixels de desplazamiento para agitar la pantalla en el eje x + int delay; // Retraso entre cada desplazamiento de la pantalla al agitarse + int counter; // Contador para el retraso + int lenght; // Cantidad de desplazamientos a realizar + int remaining; // Cantidad de desplazamientos pendientes a realizar + int origin; // Valor inicial de la pantalla para dejarla igual tras el desplazamiento + } shake; // Estructura para generar el efecto de agitación + + // Inicializa las variables + void init(); + + // Calcula el desplazamiento vertical inicial + int getInitialVerticalDesp(); + +public: + // Constructor + GameLogo(SDL_Renderer *renderer, Screen *screen, Asset *asset, int x, int y); + + // Destructor + ~GameLogo(); + + // Pinta la clase en pantalla + void render(); + + // Actualiza la lógica de la clase + void update(); + + // Activa la clase + void enable(); + + // Indica si ha terminado la animación + bool hasFinished(); + + // Recarga las texturas + void reLoad(); +}; + +#endif \ No newline at end of file diff --git a/source/hiscore_table.cpp b/source/hiscore_table.cpp index 3c6b076..a97bd61 100644 --- a/source/hiscore_table.cpp +++ b/source/hiscore_table.cpp @@ -80,7 +80,7 @@ void HiScoreTable::update() if (manualQuit) { section->name = SECTION_PROG_TITLE; - section->subsection = SUBSECTION_TITLE_3; + section->subsection = SUBSECTION_TITLE_2; } } } diff --git a/source/instructions.cpp b/source/instructions.cpp index 2989eae..07d6a3a 100644 --- a/source/instructions.cpp +++ b/source/instructions.cpp @@ -100,7 +100,7 @@ void Instructions::update() if (manualQuit) { section->name = SECTION_PROG_TITLE; - section->subsection = SUBSECTION_TITLE_3; + section->subsection = SUBSECTION_TITLE_2; } } } diff --git a/source/title.cpp b/source/title.cpp index a7df137..8aa8a57 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -16,15 +16,6 @@ Title::Title(SDL_Renderer *renderer, Screen *screen, Input *input, Asset *asset, eventHandler = new SDL_Event(); fade = new Fade(renderer); - dustTexture = new Texture(renderer, asset->get("title_dust.png")); - coffeeTexture = new Texture(renderer, asset->get("title_coffee.png")); - crisisTexture = new Texture(renderer, asset->get("title_crisis.png")); - - coffeeBitmap = new SmartSprite(coffeeTexture, renderer); - crisisBitmap = new SmartSprite(crisisTexture, renderer); - dustBitmapL = new AnimatedSprite(dustTexture, renderer, asset->get("title_dust.ani")); - dustBitmapR = new AnimatedSprite(dustTexture, renderer, asset->get("title_dust.ani")); - text1 = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer); text2 = new Text(asset->get("8bithud.png"), asset->get("8bithud.txt"), renderer); @@ -37,8 +28,8 @@ Title::Title(SDL_Renderer *renderer, Screen *screen, Input *input, Asset *asset, tiledbg = new Tiledbg(renderer, screen, asset, {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT}); - // Sonidos - crashSound = JA_LoadSound(asset->get("title.wav").c_str()); + gameLogo = new GameLogo(renderer, screen, asset, GAMECANVAS_CENTER_X, GAMECANVAS_FIRST_QUARTER_Y + 20); + gameLogo->enable(); // Musicas titleMusic = JA_LoadMusic(asset->get("title.ogg").c_str()); @@ -54,27 +45,13 @@ Title::~Title() delete eventHandler; delete fade; - dustTexture->unload(); - delete dustTexture; - - coffeeTexture->unload(); - delete coffeeTexture; - - crisisTexture->unload(); - delete crisisTexture; - - delete coffeeBitmap; - delete crisisBitmap; - delete dustBitmapL; - delete dustBitmapR; - delete text1; delete text2; delete backgroundObj; delete tiledbg; + delete gameLogo; - JA_DeleteSound(crashSound); JA_DeleteMusic(titleMusic); } @@ -84,7 +61,6 @@ void Title::init() // Inicializa variables section->subsection = SUBSECTION_TITLE_1; counter = TITLE_COUNTER; - menuVisible = false; nextSection.name = SECTION_PROG_GAME; postFade = 0; ticks = 0; @@ -121,53 +97,6 @@ void Title::init() options->input[1].name = availableInputDevices[deviceIndex[1]].name; options->input[1].deviceType = availableInputDevices[deviceIndex[1]].deviceType; } - - // Inicializa el bitmap de 'Coffee' - coffeeBitmap->init(); - coffeeBitmap->setPosX(45); - coffeeBitmap->setPosY(11 - 200); - coffeeBitmap->setWidth(167); - coffeeBitmap->setHeight(46); - coffeeBitmap->setVelX(0.0f); - coffeeBitmap->setVelY(2.5f); - coffeeBitmap->setAccelX(0.0f); - coffeeBitmap->setAccelY(0.1f); - coffeeBitmap->setSpriteClip(0, 0, 167, 46); - coffeeBitmap->setEnabled(true); - coffeeBitmap->setEnabledCounter(0); - coffeeBitmap->setDestX(45); - coffeeBitmap->setDestY(11); - - // Inicializa el bitmap de 'Crisis' - crisisBitmap->init(); - crisisBitmap->setPosX(60); - crisisBitmap->setPosY(57 + 200); - crisisBitmap->setWidth(137); - crisisBitmap->setHeight(46); - crisisBitmap->setVelX(0.0f); - crisisBitmap->setVelY(-2.5f); - crisisBitmap->setAccelX(0.0f); - crisisBitmap->setAccelY(-0.1f); - crisisBitmap->setSpriteClip(0, 0, 137, 46); - crisisBitmap->setEnabled(true); - crisisBitmap->setEnabledCounter(0); - crisisBitmap->setDestX(60); - crisisBitmap->setDestY(57); - - // Inicializa el bitmap de 'DustRight' - dustBitmapR->resetAnimation(); - dustBitmapR->setPosX(218); - dustBitmapR->setPosY(47); - dustBitmapR->setWidth(16); - dustBitmapR->setHeight(16); - dustBitmapR->setFlip(SDL_FLIP_HORIZONTAL); - - // Inicializa el bitmap de 'DustLeft' - dustBitmapL->resetAnimation(); - dustBitmapL->setPosX(33); - dustBitmapL->setPosY(47); - dustBitmapL->setWidth(16); - dustBitmapL->setHeight(16); } // Actualiza las variables del objeto @@ -182,55 +111,18 @@ void Title::update() // Actualiza el objeto 'background' backgroundObj->update(); - // Se realizan diferentes cosas en funcion de la subsección actual - switch (section->subsection) + // Sección 1 - Titulo animandose + if (section->subsection == SUBSECTION_TITLE_1) { - // Sección 1 - Titulo desplazandose - case SUBSECTION_TITLE_1: - { - // Actualiza los objetos - coffeeBitmap->update(); - crisisBitmap->update(); - - // Si los objetos han llegado a su destino, cambiamos de Sección - if (coffeeBitmap->hasFinished() && crisisBitmap->hasFinished()) + gameLogo->update(); + if (gameLogo->hasFinished()) { section->subsection = SUBSECTION_TITLE_2; - - // Pantallazo blanco - screen->setFlash({0xFF, 0xFF, 0xFF}, 5); - - // Reproduce el efecto sonoro - JA_PlaySound(crashSound); } } - break; - // Sección 2 - Titulo vibrando - case SUBSECTION_TITLE_2: - { - // Agita el logo - static const int v[] = {-1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 0}; - static const int a = coffeeBitmap->getPosX(); - static const int b = crisisBitmap->getPosX(); - static int step = 0; - - coffeeBitmap->setPosX(a + v[step / 3]); - crisisBitmap->setPosX(b + v[step / 3]); - dustBitmapR->update(); - dustBitmapL->update(); - - step++; - if (step == 33) - { - section->subsection = SUBSECTION_TITLE_3; - step = 0; - } - } - break; - - // Sección 3 - La pantalla de titulo con el menú y la música - case SUBSECTION_TITLE_3: + // Sección 2 - La pantalla con el titulo, el fondo animado y la música + else if (section->subsection == SUBSECTION_TITLE_2) { if (counter > 0) { @@ -242,9 +134,11 @@ void Title::update() JA_PlayMusic(titleMusic); } - // Actualiza los objetos - dustBitmapR->update(); - dustBitmapL->update(); + // Actualiza el logo con el título del juego + gameLogo->update(); + + // Actualiza el mosaico de fondo + tiledbg->update(); // Actualiza la lógica del titulo fade->update(); @@ -292,9 +186,6 @@ void Title::update() break; } } - - // Actualiza el mosaico de fondo - tiledbg->update(); } else if (counter == 0) { @@ -327,12 +218,6 @@ void Title::update() demo = true; } } - - break; - - default: - break; - } } } @@ -349,15 +234,10 @@ void Title::render() tiledbg->render(); // backgroundObj->render(); - // Dibuja el logo - coffeeBitmap->render(); - crisisBitmap->render(); + // Dinuja el logo con el título del juego + gameLogo->render(); - // Dibuja el polvillo del logo - dustBitmapR->render(); - dustBitmapL->render(); - - if (section->subsection == SUBSECTION_TITLE_3) + if (section->subsection == SUBSECTION_TITLE_2) { // PRESS ANY KEY! if (counter % 50 > 14) @@ -582,8 +462,6 @@ void Title::checkInputDevices() // Recarga las texturas void Title::reLoadTextures() { - dustTexture->reLoad(); - coffeeTexture->reLoad(); - crisisTexture->reLoad(); + gameLogo->reLoad(); tiledbg->reLoad(); } \ No newline at end of file diff --git a/source/title.h b/source/title.h index 20d3754..b42f3db 100644 --- a/source/title.h +++ b/source/title.h @@ -20,6 +20,7 @@ #include "lang.h" #include "background.h" #include "tiledbg.h" +#include "game_logo.h" #ifndef TITLE_H #define TITLE_H @@ -49,16 +50,7 @@ private: section_t *section; // Indicador para el bucle del titulo Background *backgroundObj; // Objeto para dibujar el fondo del juego Tiledbg *tiledbg; // Objeto para dibujar el mosaico animado de fondo - - Texture *dustTexture; // Textura con los graficos del polvo - Texture *coffeeTexture; // Textura con los graficos de la palabra coffee - Texture *crisisTexture; // Textura con los graficos de la plabra crisis - - AnimatedSprite *dustBitmapL; // Sprite con la el polvo que aparece al colisionar el texto de la pantalla de titulo - AnimatedSprite *dustBitmapR; // Sprite con la el polvo que aparece al colisionar el texto de la pantalla de titulo - - SmartSprite *coffeeBitmap; // Sprite con la palabra COFFEE para la pantalla de titulo - SmartSprite *crisisBitmap; // Sprite con la palabra CRISIS para la pantalla de titulo + GameLogo *gameLogo; // Objeto para dibujar el logo con el título del juego Text *text1; // Objeto de texto para poder escribir textos en pantalla Text *text2; // Objeto de texto para poder escribir textos en pantalla @@ -66,10 +58,8 @@ private: // Variable JA_Music_t *titleMusic; // Musica para el titulo - JA_Sound_t *crashSound; // Sonido con el impacto del título int counter; // Temporizador para la pantalla de titulo Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa - bool menuVisible; // Indicador para saber si se muestra el menu del titulo o la frase intermitente bool demo; // Indica si el modo demo estará activo section_t nextSection; // Indica cual es la siguiente sección a cargar cuando termine el contador del titulo Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa