From 75a18c5306ec28344e189f16fb3374539b8b0350 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 1 Jun 2024 13:11:19 +0200 Subject: [PATCH] Creada la clase para dibujar el fondo del juego --- source/background.cpp | 167 ++++++++++++++++++++++++++++++++++++++++++ source/background.h | 68 +++++++++++++++++ source/const.h | 5 +- source/game.cpp | 161 ++++++---------------------------------- source/game.h | 18 +---- 5 files changed, 263 insertions(+), 156 deletions(-) create mode 100644 source/background.cpp create mode 100644 source/background.h diff --git a/source/background.cpp b/source/background.cpp new file mode 100644 index 0000000..d9472bc --- /dev/null +++ b/source/background.cpp @@ -0,0 +1,167 @@ +#include "background.h" + +// Constructor +Background::Background(SDL_Renderer *renderer, Screen *screen, Asset *asset) +{ + // Copia los punteros + this->renderer = renderer; + this->screen = screen; + this->asset = asset; + + // Carga las texturas + buildingsTexture = new Texture(renderer, asset->get("game_buildings.png")); + cloudsTexture = new Texture(renderer, asset->get("game_clouds.png")); + grassTexture = new Texture(renderer, asset->get("game_grass.png")); + gradientsTexture = new Texture(renderer, asset->get("game_sky_colors.png")); + + // Crea los sprites + clouds1A = new MovingSprite(0, 0, 256, 52, -0.4f, 0.0f, 0.0f, 0.0f, cloudsTexture, renderer); + clouds1B = new MovingSprite(256, 0, 256, 52, -0.4f, 0.0f, 0.0f, 0.0f, cloudsTexture, renderer); + clouds2A = new MovingSprite(0, 52, 256, 32, -0.2f, 0.0f, 0.0f, 0.0f, cloudsTexture, renderer); + clouds2B = new MovingSprite(256, 52, 256, 32, -0.2f, 0.0f, 0.0f, 0.0f, cloudsTexture, renderer); + + buildingsSprite = new Sprite(0, 0, 256, 160, buildingsTexture, renderer); + gradientSprite = new Sprite(0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT, gradientsTexture, renderer); + grassSprite = new Sprite(0, 0, 256, 6, grassTexture, renderer); + + // Inicializa variables + clouds1A->setSpriteClip(0, 0, 256, 52); + clouds1B->setSpriteClip(0, 0, 256, 52); + clouds2A->setSpriteClip(0, 52, 256, 32); + clouds2B->setSpriteClip(0, 52, 256, 32); + grassSprite->setPosY(154); + + gradientRect[0] = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT}; + gradientRect[1] = {256, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT}; + gradientRect[2] = {0, 192, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT}; + gradientRect[3] = {256, 192, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT}; + + gradientNumber = 0; + alpha = 0; + cloudsSpeed = 0; + transition = 0; + counter = 0; +} + +// Destructor +Background::~Background() +{ + buildingsTexture->unload(); + delete buildingsTexture; + + cloudsTexture->unload(); + delete cloudsTexture; + + grassTexture->unload(); + delete grassTexture; + + gradientsTexture->unload(); + delete gradientsTexture; + + delete clouds1A; + delete clouds1B; + delete clouds2A; + delete clouds2B; + delete buildingsSprite; + delete gradientSprite; + delete grassSprite; +} + +// Actualiza la lógica del objeto +void Background::update() +{ + // Aplica la velocidad calculada a las nubes + clouds1A->setVelX(cloudsSpeed); + clouds1B->setVelX(cloudsSpeed); + clouds2A->setVelX(cloudsSpeed / 2); + clouds2B->setVelX(cloudsSpeed / 2); + + // Mueve las nubes + clouds1A->move(); + clouds1B->move(); + clouds2A->move(); + clouds2B->move(); + + // Calcula el offset de las nubes + if (clouds1A->getPosX() < -clouds1A->getWidth()) + { + clouds1A->setPosX(clouds1A->getWidth()); + } + + if (clouds1B->getPosX() < -clouds1B->getWidth()) + { + clouds1B->setPosX(clouds1B->getWidth()); + } + + if (clouds2A->getPosX() < -clouds2A->getWidth()) + { + clouds2A->setPosX(clouds2A->getWidth()); + } + + if (clouds2B->getPosX() < -clouds2B->getWidth()) + { + clouds2B->setPosX(clouds2B->getWidth()); + } + + // Calcula el frame de la hierba + grassSprite->setSpriteClip(0, (6 * (counter / 20 % 2)), 256, 6); + + // Calcula el valor de alpha + alpha = std::max((255 - (int)(255 * transition)), 0); + + // Incrementa el contador + counter++; +} + +// Dibuja el objeto +void Background::render() +{ + // Dibuja el gradiente 2 + gradientSprite->setSpriteClip(gradientRect[(gradientNumber + 1) % 4]); + gradientsTexture->setAlpha(255); + gradientSprite->render(); + + // Dibuja el gradiente 1 con una opacidad cada vez menor + gradientSprite->setSpriteClip(gradientRect[gradientNumber]); + gradientsTexture->setAlpha(alpha); + gradientSprite->render(); + + // Dibuja las nubes + clouds1A->render(); + clouds1B->render(); + clouds2A->render(); + clouds2B->render(); + + // Dibuja los edificios + buildingsSprite->render(); + + // Dibuja la hierba + grassSprite->render(); +} + +// Vuelve a cargar las texturas +void Background::reloadTextures() +{ + buildingsTexture->reLoad(); + cloudsTexture->reLoad(); + grassTexture->reLoad(); + gradientsTexture->reLoad(); +} + +// Ajusta el valor de la variable +void Background::setCloudsSpeed(float value) +{ + cloudsSpeed = value; +} + +// Ajusta el valor de la variable +void Background::setGradientNumber(int value) +{ + gradientNumber = value % 4; +} + +// Ajusta el valor de la variable +void Background::setTransition(float value) +{ + transition = value; +} \ No newline at end of file diff --git a/source/background.h b/source/background.h new file mode 100644 index 0000000..204b45c --- /dev/null +++ b/source/background.h @@ -0,0 +1,68 @@ +#pragma once + +#include +#include "common/screen.h" +#include "common/asset.h" +#include "common/movingsprite.h" + +#ifndef BACKGROUND_H +#define BACKGROUND_H + +// Clase Background +class Background +{ +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 + + // Variables + SDL_Rect gradientRect[4]; // Vector con las coordenadas de los 4 degradados para el cielo + int gradientNumber; // Indica el número de degradado de fondo que se va a dibujar + int alpha; // Transparencia entre los dos degradados + float cloudsSpeed; // Velocidad a la que se desplazan las nubes + float transition; // Nivel de transición del fondo 0..1 + int counter; // Contador interno + + Texture *buildingsTexture; // Textura con los edificios de fondo + Texture *cloudsTexture; // Textura con las nubes de fondo + Texture *grassTexture; // Textura con la hierba del suelo + Texture *gradientsTexture; // Textura con los diferentes colores de fondo del juego + + MovingSprite *clouds1A; // Sprite para las nubes superiores + MovingSprite *clouds1B; // Sprite para las nubes superiores + MovingSprite *clouds2A; // Sprite para las nubes inferiores + MovingSprite *clouds2B; // Sprite para las nubes inferiores + + Sprite *buildingsSprite; // Sprite con los edificios de fondo + Sprite *gradientSprite; // Sprite con los graficos del degradado de color de fondo + Sprite *grassSprite; // Sprite para la hierba + +public: + // Constructor + Background(SDL_Renderer *renderer, Screen *screen, Asset *asset); + + // Destructor + ~Background(); + + // Actualiza la lógica del objeto + void update(); + + // Dibuja el objeto + void render(); + + // Vuelve a cargar las texturas + void reloadTextures(); + + // Ajusta el valor de la variable + void setCloudsSpeed(float value); + + // Ajusta el valor de la variable + void setGradientNumber(int value); + + // Ajusta el valor de la variable + void setTransition(float value); +}; + +#endif \ No newline at end of file diff --git a/source/const.h b/source/const.h index 8bd8db1..35972e6 100644 --- a/source/const.h +++ b/source/const.h @@ -15,9 +15,12 @@ #define GAMECANVAS_WIDTH 256 #define GAMECANVAS_HEIGHT 192 +// Marcador +const int SCOREBOARD_HEIGHT = (4 * BLOCK); + // Zona de juego const int PLAY_AREA_TOP = (0 * BLOCK); -const int PLAY_AREA_BOTTOM = GAMECANVAS_HEIGHT - (4 * BLOCK); +const int PLAY_AREA_BOTTOM = GAMECANVAS_HEIGHT - SCOREBOARD_HEIGHT; const int PLAY_AREA_LEFT = (0 * BLOCK); const int PLAY_AREA_RIGHT = GAMECANVAS_WIDTH - (0 * BLOCK); const int PLAY_AREA_WIDTH = PLAY_AREA_RIGHT - PLAY_AREA_LEFT; diff --git a/source/game.cpp b/source/game.cpp index 4ccfe7a..a0326bc 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -28,6 +28,7 @@ Game::Game(int numPlayers, int currentStage, SDL_Renderer *renderer, Screen *scr fade = new Fade(renderer); eventHandler = new SDL_Event(); scoreboard = new Scoreboard(renderer, screen, asset, lang, options); + background = new Background(renderer, screen, asset); // Carga los recursos loadMedia(); @@ -38,19 +39,10 @@ Game::Game(int numPlayers, int currentStage, SDL_Renderer *renderer, Screen *scr // Establece la máxima puntuación desde fichero o desde las puntuaciones online setHiScore(); - clouds1A = new MovingSprite(0, 0, 256, 52, -0.4f, 0.0f, 0.0f, 0.0f, gameCloudsTexture, renderer); - clouds1B = new MovingSprite(256, 0, 256, 52, -0.4f, 0.0f, 0.0f, 0.0f, gameCloudsTexture, renderer); - clouds2A = new MovingSprite(0, 52, 256, 32, -0.2f, 0.0f, 0.0f, 0.0f, gameCloudsTexture, renderer); - clouds2B = new MovingSprite(256, 52, 256, 32, -0.2f, 0.0f, 0.0f, 0.0f, gameCloudsTexture, renderer); - n1000Sprite = new SmartSprite(gameTextTexture, renderer); n2500Sprite = new SmartSprite(gameTextTexture, renderer); n5000Sprite = new SmartSprite(gameTextTexture, renderer); - buildingsSprite = new Sprite(0, 0, 256, 160, gameBuildingsTexture, renderer); - - skyColorsSprite = new Sprite(0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT, gameSkyColorsTexture, renderer); - grassSprite = new Sprite(0, 0, 256, 6, gameGrassTexture, renderer); gameOverSprite = new Sprite(16, 80, 128, 96, gameOverTexture, renderer); gameOverEndSprite = new Sprite(PLAY_AREA_CENTER_X - gameOverEndTexture->getWidth() / 2, 80, 128, 96, gameOverEndTexture, renderer); @@ -75,18 +67,6 @@ Game::~Game() bulletTexture->unload(); delete bulletTexture; - gameBuildingsTexture->unload(); - delete gameBuildingsTexture; - - gameCloudsTexture->unload(); - delete gameCloudsTexture; - - gameGrassTexture->unload(); - delete gameGrassTexture; - - gameSkyColorsTexture->unload(); - delete gameSkyColorsTexture; - gameTextTexture->unload(); delete gameTextTexture; @@ -145,6 +125,7 @@ Game::~Game() balloonTextures.clear(); delete scoreboard; + delete background; delete text; delete textBig; @@ -154,17 +135,9 @@ Game::~Game() delete pauseMenu; delete fade; delete eventHandler; - delete clouds1A; - delete clouds1B; - delete clouds2A; - delete clouds2B; delete n1000Sprite; delete n2500Sprite; delete n5000Sprite; - delete buildingsSprite; - - delete skyColorsSprite; - delete grassSprite; delete gameOverSprite; delete gameOverEndSprite; @@ -247,7 +220,7 @@ void Game::init() } // Variables para el marcador - scoreboard->setPos({0, 160, 256, 32}); + scoreboard->setPos({PLAY_AREA_LEFT, PLAY_AREA_BOTTOM, PLAY_AREA_WIDTH, SCOREBOARD_HEIGHT}); if (difficulty == DIFFICULTY_NORMAL) { scoreboard->setColor({46, 63, 71}); @@ -332,14 +305,6 @@ void Game::init() // Inicializa el objeto para el fundido fade->init(0x27, 0x27, 0x36); - // Sprites - clouds1A->setSpriteClip(0, 0, 256, 52); - clouds1B->setSpriteClip(0, 0, 256, 52); - clouds2A->setSpriteClip(0, 52, 256, 32); - clouds2B->setSpriteClip(0, 52, 256, 32); - - grassSprite->setPosY(154); - // Con los globos creados, calcula el nivel de amenaza evaluateAndSetMenace(); @@ -387,12 +352,6 @@ void Game::init() n5000Sprite->setEnabledCounter(0); n5000Sprite->setDestX(0); n5000Sprite->setDestY(0); - - // Los fondos - skyColorsRect[0] = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT}; - skyColorsRect[1] = {256, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT}; - skyColorsRect[2] = {0, 192, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT}; - skyColorsRect[3] = {256, 192, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT}; } // Carga los recursos necesarios para la sección 'Game' @@ -406,10 +365,6 @@ void Game::loadMedia() // Texturas bulletTexture = new Texture(renderer, asset->get("bullet.png")); - gameBuildingsTexture = new Texture(renderer, asset->get("game_buildings.png")); - gameCloudsTexture = new Texture(renderer, asset->get("game_clouds.png")); - gameGrassTexture = new Texture(renderer, asset->get("game_grass.png")); - gameSkyColorsTexture = new Texture(renderer, asset->get("game_sky_colors.png")); gameTextTexture = new Texture(renderer, asset->get("game_text.png")); gameOverTexture = new Texture(renderer, asset->get("menu_game_over.png")); gameOverEndTexture = new Texture(renderer, asset->get("menu_game_over_end.png")); @@ -2704,100 +2659,31 @@ void Game::update() // Actualiza el fondo void Game::updateBackground() { - if (!gameCompleted) - { // Si el juego no esta completo, la velocidad de las nubes es igual a los globos explotados - cloudsSpeed = balloonsPopped; - } - else - { // Si el juego está completado, se reduce la velocidad de las nubes - if (cloudsSpeed > 400) + // Si el juego está completado, se reduce la velocidad de las nubes + if (gameCompleted) + { + if (balloonsPopped > 400) { - cloudsSpeed -= 25; + balloonsPopped -= 25; } else { - cloudsSpeed = 200; + balloonsPopped = 200; } } // Calcula la velocidad en función de los globos explotados y el total de globos a explotar para acabar el juego - const float speed = (-0.2f) + (-3.00f * ((float)cloudsSpeed / (float)totalPowerToCompleteGame)); + const float speed = (-0.2f) + (-3.00f * ((float)balloonsPopped / (float)totalPowerToCompleteGame)); - // Aplica la velocidad calculada a las nubes - clouds1A->setVelX(speed); - clouds1B->setVelX(speed); - clouds2A->setVelX(speed / 2); - clouds2B->setVelX(speed / 2); + // Aplica la velocidad calculada para las nubes + background->setCloudsSpeed(speed); + const float gradientNumber = std::min(((float)balloonsPopped / 1250.0f), 3.0f); + const float percent = gradientNumber - (int)gradientNumber; + background->setGradientNumber((int)gradientNumber); + background->setTransition(percent); - // Mueve las nubes - clouds1A->move(); - clouds1B->move(); - clouds2A->move(); - clouds2B->move(); - - // Calcula el offset de las nubes - if (clouds1A->getPosX() < -clouds1A->getWidth()) - { - clouds1A->setPosX(clouds1A->getWidth()); - } - - if (clouds1B->getPosX() < -clouds1B->getWidth()) - { - clouds1B->setPosX(clouds1B->getWidth()); - } - - if (clouds2A->getPosX() < -clouds2A->getWidth()) - { - clouds2A->setPosX(clouds2A->getWidth()); - } - - if (clouds2B->getPosX() < -clouds2B->getWidth()) - { - clouds2B->setPosX(clouds2B->getWidth()); - } - - // Calcula el frame de la hierba - grassSprite->setSpriteClip(0, (6 * (counter / 20 % 2)), 256, 6); - - // Mueve los edificios en funcion de si está activo el efecto de agitarlos - if (effect.shake) - { - buildingsSprite->setPosX(((effect.shakeCounter % 2) * 2) - 1); - } - else - { - buildingsSprite->setPosX(0); - } -} - -// Dibuja el fondo -void Game::renderBackground() -{ - const float gradientNumber = std::min(((float)balloonsPopped / 1250.0f), 3.0f); - const float percent = gradientNumber - (int)gradientNumber; - const int alpha = std::max((255 - (int)(255 * percent)), 0); - - // Dibuja el gradiente 2 - skyColorsSprite->setSpriteClip(skyColorsRect[((int)gradientNumber + 1) % 4]); - gameSkyColorsTexture->setAlpha(255); - skyColorsSprite->render(); - - // Dibuja el gradiente 1 con una opacidad cada vez menor - skyColorsSprite->setSpriteClip(skyColorsRect[(int)gradientNumber]); - gameSkyColorsTexture->setAlpha(alpha); - skyColorsSprite->render(); - - // Dibuja las nubes - clouds1A->render(); - clouds1B->render(); - clouds2A->render(); - clouds2B->render(); - - // Dinuja los edificios - buildingsSprite->render(); - - // Dibuja la hierba - grassSprite->render(); + // Actualiza el objeto + background->update(); } // Dibuja la linea que separa la zona ade juego del marcador @@ -2805,7 +2691,7 @@ void Game::renderSeparator() { // Dibuja la linea que separa el marcador de la zona de juego SDL_SetRenderDrawColor(renderer, 13, 26, 43, 255); - SDL_RenderDrawLine(renderer, 0, 160, 255, 160); + SDL_RenderDrawLine(renderer, PLAY_AREA_LEFT, PLAY_AREA_BOTTOM, PLAY_AREA_RIGHT, PLAY_AREA_BOTTOM); } // Dibuja el juego @@ -2818,7 +2704,7 @@ void Game::render() screen->clean(bgColor); // Dibuja los objetos - renderBackground(); + background->render(); renderBalloons(); renderBullets(); renderMessages(); @@ -3287,7 +3173,7 @@ void Game::renderPausedGame() // Pinta el escenario { - renderBackground(); + background->render(); renderBalloons(); renderBullets(); renderMessages(); @@ -3770,11 +3656,8 @@ void Game::reloadTextures() } bulletTexture->reLoad(); - gameBuildingsTexture->reLoad(); - gameCloudsTexture->reLoad(); - gameGrassTexture->reLoad(); - gameSkyColorsTexture->reLoad(); gameTextTexture->reLoad(); + background->reloadTextures(); } // Establece la máxima puntuación desde fichero o desde las puntuaciones online diff --git a/source/game.h b/source/game.h index 2074380..2af2ba8 100644 --- a/source/game.h +++ b/source/game.h @@ -19,6 +19,7 @@ #include "item.h" #include "player.h" #include "scoreboard.h" +#include "background.h" #include #ifndef GAME_H @@ -123,6 +124,7 @@ private: Input *input; // Manejador de entrada section_t *section; // Seccion actual dentro del juego Scoreboard *scoreboard; // Objeto para dibujar el marcador + Background *background; // Objetio para dibujar el fondo del juego std::vector players; // Vector con los jugadores std::vector balloons; // Vector con los globos @@ -137,10 +139,6 @@ private: std::vector player2Textures; // Vector con las texturas del jugador std::vector> playerTextures; // Vector con todas las texturas de los jugadores; - Texture *gameBuildingsTexture; // Textura con los edificios de fondo - Texture *gameCloudsTexture; // Textura con las nubes de fondo - Texture *gameGrassTexture; // Textura con la hierba del suelo - Texture *gameSkyColorsTexture; // Textura con los diferentes colores de fondo del juego Texture *gameTextTexture; // Textura para los sprites con textos Texture *gameOverTexture; // Textura para la pantalla de game over Texture *gameOverEndTexture; // Textura para la pantalla de game over de acabar el juego @@ -160,17 +158,10 @@ private: Fade *fade; // Objeto para renderizar fades SDL_Event *eventHandler; // Manejador de eventos - MovingSprite *clouds1A; // Sprite para las nubes superiores - MovingSprite *clouds1B; // Sprite para las nubes superiores - MovingSprite *clouds2A; // Sprite para las nubes inferiores - MovingSprite *clouds2B; // Sprite para las nubes inferiores SmartSprite *n1000Sprite; // Sprite con el texto 1.000 SmartSprite *n2500Sprite; // Sprite con el texto 2.500 SmartSprite *n5000Sprite; // Sprite con el texto 5.000 - Sprite *buildingsSprite; // Sprite con los edificios de fondo - Sprite *skyColorsSprite; // Sprite con los graficos del degradado de color de fondo - Sprite *grassSprite; // Sprite para la hierba Sprite *gameOverSprite; // Sprite para dibujar los graficos del game over Sprite *gameOverEndSprite; // Sprite para dibujar los graficos del game over de acabar el juego @@ -211,7 +202,6 @@ private: Uint16 timeStoppedCounter; // Temporizador para llevar la cuenta del tiempo detenido Uint32 counter; // Contador para el juego Uint32 scoreDataFile[TOTAL_SCORE_DATA]; // Datos del fichero de puntos - SDL_Rect skyColorsRect[4]; // Vector con las coordenadas de los 4 colores de cielo Uint16 balloonsPopped; // Lleva la cuenta de los globos explotados Uint8 lastEnemyDeploy; // Guarda cual ha sido la última formación desplegada para no repetir; int enemyDeployCounter; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero @@ -234,7 +224,6 @@ private: Uint8 lastStageReached; // Contiene el numero de la última pantalla que se ha alcanzado demo_t demo; // Variable con todas las variables relacionadas con el modo demo int totalPowerToCompleteGame; // La suma del poder necesario para completar todas las fases - int cloudsSpeed; // Velocidad a la que se desplazan las nubes int pauseCounter; // Contador para salir del menu de pausa y volver al juego bool leavingPauseMenu; // Indica si esta saliendo del menu de pausa para volver al juego @@ -439,9 +428,6 @@ private: // Actualiza el fondo void updateBackground(); - // Dibuja el fondo - void renderBackground(); - // Gestiona la entrada durante el juego void checkGameInput();