diff --git a/data/gfx/game/game_moon.png b/data/gfx/game/game_moon.png new file mode 100644 index 0000000..7c9ddc8 Binary files /dev/null and b/data/gfx/game/game_moon.png differ diff --git a/data/gfx/game/game_sun.png b/data/gfx/game/game_sun.png new file mode 100644 index 0000000..bc63a21 Binary files /dev/null and b/data/gfx/game/game_sun.png differ diff --git a/source/background.cpp b/source/background.cpp index 8cb2208..f3d5426 100644 --- a/source/background.cpp +++ b/source/background.cpp @@ -2,12 +2,13 @@ #include // Para SDL_BLENDMODE_BLEND #include // Para SDL_PIXELFORMAT_RGBA8888 #include // Para clamp, max -#include "moving_sprite.h" // Para MovingSprite -#include "param.h" // Para Param, ParamBackground, param -#include "resource.h" // Para Resource -#include "screen.h" // Para Screen -#include "sprite.h" // Para Sprite -#include "texture.h" // Para Texture +#include +#include "moving_sprite.h" // Para MovingSprite +#include "param.h" // Para Param, ParamBackground, param +#include "resource.h" // Para Resource +#include "screen.h" // Para Screen +#include "sprite.h" // Para Sprite +#include "texture.h" // Para Texture // Constructor Background::Background() @@ -18,16 +19,22 @@ Background::Background() bottom_clouds_texture_(Resource::get()->getTexture("game_clouds2.png")), grass_texture_(Resource::get()->getTexture("game_grass.png")), gradients_texture_(Resource::get()->getTexture("game_sky_colors.png")), + sun_texture_(Resource::get()->getTexture("game_sun.png")), + moon_texture_(Resource::get()->getTexture("game_moon.png")), rect_({0, 0, gradients_texture_->getWidth() / 2, gradients_texture_->getHeight() / 2}), src_rect_({0, 0, 320, 240}), dst_rect_({0, 0, 320, 240}), base_(rect_.h), - color_(Color(param.background.attenuate_color.r, param.background.attenuate_color.g, param.background.attenuate_color.b)), + attenuate_color_(Color(param.background.attenuate_color.r, param.background.attenuate_color.g, param.background.attenuate_color.b)), alpha_color_text_(param.background.attenuate_alpha), alpha_color_text_temp_(param.background.attenuate_alpha) { + // Precalcula rutas + createSunPath(); + createMoonPath(); + // Inicializa variables { gradient_rect_[0] = {0, 0, rect_.w, rect_.h}; @@ -55,9 +62,11 @@ Background::Background() bottom_clouds_sprite_a_ = std::make_unique(bottom_clouds_texture_, (SDL_Rect){0, bottom_clouds_y, rect_.w, bottom_clouds_texture_->getHeight()}); bottom_clouds_sprite_b_ = std::make_unique(bottom_clouds_texture_, (SDL_Rect){rect_.w, bottom_clouds_y, rect_.w, bottom_clouds_texture_->getHeight()}); - buildings_sprite_ = std::make_unique(buildings_texture_, 0, 0, buildings_texture_->getWidth(), buildings_texture_->getHeight()); + buildings_sprite_ = std::make_unique(buildings_texture_); gradient_sprite_ = std::make_unique(gradients_texture_, 0, 0, rect_.w, rect_.h); grass_sprite_ = std::make_unique(grass_texture_, 0, 0, grass_texture_->getWidth(), grass_texture_->getHeight() / 2); + sun_sprite_ = std::make_unique(sun_texture_); + moon_sprite_ = std::make_unique(moon_texture_); } // Inicializa objetos @@ -79,6 +88,8 @@ Background::Background() buildings_sprite_->setY(base_ - buildings_sprite_->getHeight()); grass_sprite_->setY(base_ - grass_sprite_->getHeight()); + sun_sprite_->setPosition(sun_path_.front()); + moon_sprite_->setPosition(moon_path_.front()); } // Crea la textura para componer el fondo @@ -88,7 +99,7 @@ Background::Background() // Crea la textura para atenuar el fondo color_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h); SDL_SetTextureBlendMode(color_texture_, SDL_BLENDMODE_BLEND); - setColor(color_); + setColor(attenuate_color_); SDL_SetTextureAlphaMod(color_texture_, alpha_color_text_); } @@ -114,6 +125,10 @@ void Background::update() // Calcula el valor de alpha_ alpha_ = std::max((255 - (int)(255 * transition_)), 0); + // Mueve el sol + sun_sprite_->setPosition(sun_path_.at(sun_index_)); + moon_sprite_->setPosition(moon_path_.at(moon_index_)); + // Incrementa el contador ++counter_; @@ -181,6 +196,10 @@ void Background::fillCanvas() // Dibuja el gradiente de fondo renderGradient(); + // Dibuja los astros + sun_sprite_->render(); + moon_sprite_->render(); + // Dibuja las nubes de arriba renderTopClouds(); @@ -250,13 +269,13 @@ void Background::setPos(SDL_Rect pos) // Establece el color_ de atenuación void Background::setColor(Color color) { - color_ = color; + attenuate_color_ = color; // Colorea la textura auto temp = SDL_GetRenderTarget(renderer_); SDL_SetRenderTarget(renderer_, color_texture_); - SDL_SetRenderDrawColor(renderer_, color_.r, color_.g, color_.b, 255); + SDL_SetRenderDrawColor(renderer_, attenuate_color_.r, attenuate_color_.g, attenuate_color_.b, 255); SDL_RenderClear(renderer_); SDL_SetRenderTarget(renderer_, temp); @@ -322,4 +341,60 @@ void Background::updateClouds() { bottom_clouds_sprite_b_->setPosX(bottom_clouds_sprite_b_->getWidth()); } +} + +// Precalcula el vector con el recorrido del sol +void Background::createSunPath() +{ + constexpr int OFFSET_X = 94; // Desplazamiento en la textura del sol hasta el sol + constexpr int OFFSET_Y = 48; // Desplazamiento en la textura del sol hasta el sol + constexpr int CENTER_X = 270; + const int center_y = base_ - 30; + constexpr int RADIUS = 130; + const int EXTRA_PIXELS = 30; // Píxeles adicionales para la línea recta + + // Generar puntos de la curva desde 90 a 180 grados + for (double theta = M_PI / 2; theta <= M_PI; theta += 0.01) + { + int x = CENTER_X + static_cast(RADIUS * cos(theta)); + int y = center_y - static_cast(RADIUS * sin(theta)); // Nota: y está invertido en la pantalla + sun_path_.push_back({x - OFFSET_X, y - OFFSET_Y}); + } + + // Agregar puntos en línea recta después de la curva + SDL_Point last_point = sun_path_.back(); + for (int i = 1; i <= EXTRA_PIXELS; ++i) + { + sun_path_.push_back({last_point.x, last_point.y + i}); + } +} + +// Precalcula el vector con el recorrido de la luna +void Background::createMoonPath() +{ + constexpr int CENTER_X = 100; + const int center_y = base_ - 50; + constexpr int RADIUS = 140; + + // Generar puntos de la curva desde 0 a 90 grados + for (double theta = 0; theta <= M_PI / 2; theta += 0.01) + { + int x = CENTER_X + static_cast(RADIUS * cos(theta)); + int y = center_y - static_cast(RADIUS * sin(theta)); // Nota: y está invertido en la pantalla + moon_path_.push_back({x, y}); + } +} + +// Establece la posición del sol +void Background::setSunProgression(float progress) +{ + progress = std::clamp(progress, 0.0f, 1.0f); + sun_index_ = static_cast(progress * (sun_path_.size() - 1)); +} + +// Establece la posición de la luna +void Background::setMoonProgression(float progress) +{ + progress = std::clamp(progress, 0.0f, 1.0f); + moon_index_ = static_cast(progress * (moon_path_.size() - 1)); } \ No newline at end of file diff --git a/source/background.h b/source/background.h index d323b91..7db1c9e 100644 --- a/source/background.h +++ b/source/background.h @@ -51,6 +51,8 @@ private: std::shared_ptr bottom_clouds_texture_; // Textura con las nubes de fondo std::shared_ptr grass_texture_; // Textura con la hierba del suelo std::shared_ptr gradients_texture_; // Textura con los diferentes colores de fondo del juego + std::shared_ptr sun_texture_; // Textura con el sol + std::shared_ptr moon_texture_; // Textura con la luna std::unique_ptr top_clouds_sprite_a_; // Sprite para las nubes superiores std::unique_ptr top_clouds_sprite_b_; // Sprite para las nubes superiores @@ -60,26 +62,32 @@ private: std::unique_ptr buildings_sprite_; // Sprite con los edificios de fondo std::unique_ptr gradient_sprite_; // Sprite con los graficos del degradado de color de fondo std::unique_ptr grass_sprite_; // Sprite para la hierba + std::unique_ptr sun_sprite_; // Sprite para el sol + std::unique_ptr moon_sprite_; // Sprite para la luna SDL_Texture *canvas_; // Textura para componer el fondo SDL_Texture *color_texture_; // Textura para atenuar el fondo // Variables - SDL_Rect gradient_rect_[4]; // Vector con las coordenadas de los 4 degradados para el cielo - SDL_Rect top_clouds_rect_[4]; // Vector con las coordenadas de los 4 nubes de arriba - SDL_Rect bottom_clouds_rect_[4]; // Vector con las coordenadas de los 4 nubes de abajo - int gradient_number_ = 0; // Indica el número de degradado de fondo que se va a dibujar - int alpha_ = 0; // Transparencia entre los dos degradados - float clouds_speed_ = 0; // Velocidad a la que se desplazan las nubes - float transition_ = 0; // Nivel de transición del fondo 0..1 - int counter_ = 0; // Contador interno - SDL_Rect rect_; // Tamaño del objeto fondo - SDL_Rect src_rect_; // Parte del objeto fondo que se va a dibujará en pantalla - SDL_Rect dst_rect_; // Posición donde dibujar la parte del objeto fondo que se dibujará en pantalla - int base_; // Linea de fondo coincidente con el area inferior de la zona de juego - Color color_; // Color para atenuar el fondo - int alpha_color_text_; // Alpha para atenuar el fondo - int alpha_color_text_temp_; // Valor temporal para hacer la transición de alpha + SDL_Rect gradient_rect_[4]; // Vector con las coordenadas de los 4 degradados para el cielo + SDL_Rect top_clouds_rect_[4]; // Vector con las coordenadas de los 4 nubes de arriba + SDL_Rect bottom_clouds_rect_[4]; // Vector con las coordenadas de los 4 nubes de abajo + int gradient_number_ = 0; // Indica el número de degradado de fondo que se va a dibujar + int alpha_ = 0; // Transparencia entre los dos degradados + float clouds_speed_ = 0; // Velocidad a la que se desplazan las nubes + float transition_ = 0; // Nivel de transición del fondo 0..1 + int counter_ = 0; // Contador interno + SDL_Rect rect_; // Tamaño del objeto fondo + SDL_Rect src_rect_; // Parte del objeto fondo que se va a dibujará en pantalla + SDL_Rect dst_rect_; // Posición donde dibujar la parte del objeto fondo que se dibujará en pantalla + int base_; // Linea de fondo coincidente con el area inferior de la zona de juego + Color attenuate_color_; // Color para atenuar el fondo + int alpha_color_text_; // Alpha para atenuar el fondo + int alpha_color_text_temp_; // Valor temporal para hacer la transición de alpha + std::vector sun_path_; // Vector con el recorrido del sol + std::vector moon_path_; // Vector con el recorrido de la luna + size_t sun_index_; // Posición del vector del recorrido del sol + size_t moon_index_; // Posición del vector del recorrido de la luna // Dibuja el gradiente de fondo void renderGradient(); @@ -99,6 +107,12 @@ private: // Actualiza las nubes void updateClouds(); + // Precalcula el vector con el recorrido del sol + void createSunPath(); + + // Precalcula el vector con el recorrido de la luna + void createMoonPath(); + public: // Constructor Background(); @@ -132,4 +146,10 @@ public: // Establece la transparencia de la atenuación void setAlpha(int alpha); + + // Establece la posición del sol + void setSunProgression(float progress); + + // Establece la posición de la luna + void setMoonProgression(float progress); }; \ No newline at end of file diff --git a/source/director.cpp b/source/director.cpp index ce597d4..5fa848c 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -54,7 +54,7 @@ Director::Director(int argc, const char *argv[]) section::name = section::Name::GAME; section::options = section::Options::GAME_PLAY_1P; #elif DEBUG - section::name = section::Name::GAME; + section::name = section::Name::LOGO; #else // NORMAL GAME section::name = section::Name::LOGO; section::attract_mode = section::AttractMode::TITLE_TO_DEMO; @@ -467,6 +467,8 @@ void Director::setFileList() Asset::get()->add(prefix + "/data/gfx/game/game_grass.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game/game_power_meter.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game/game_sky_colors.png", AssetType::BITMAP); + Asset::get()->add(prefix + "/data/gfx/game/game_sun.png", AssetType::BITMAP); + Asset::get()->add(prefix + "/data/gfx/game/game_moon.png", AssetType::BITMAP); } { // Intro diff --git a/source/game.cpp b/source/game.cpp index a116591..8cea7ff 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -36,6 +36,7 @@ #include "text.h" // Para Text #include "texture.h" // Para Texture #include "mouse.h" +#include "dbgtxt.h" struct JA_Sound_t; // lines 37-37 // Constructor @@ -855,8 +856,8 @@ void Game::renderPathSprites() void Game::killPlayer(std::shared_ptr &player) { if (!player->isPlaying() || player->isInvulnerable()) - { - // Si no está jugando o tiene inmunidad, no hace nada + { + // Si no está jugando o tiene inmunidad, no hace nada return; } @@ -969,9 +970,9 @@ void Game::updateBackground() } // Calcula la velocidad en función de los globos explotados y el total de globos a explotar para acabar el juego - constexpr float clouds_initial_speed = 0.05f; - constexpr float clouds_final_speed = 2.00f - clouds_initial_speed; - const float cloudsSpeed = (-clouds_initial_speed) + (-clouds_final_speed * (static_cast(Stage::total_power) / total_power_to_complete_game_)); + constexpr float CLOUDS_INITIAL_SPEED = 0.05f; + constexpr float CLOUDS_FINAL_SPEED = 2.00f - CLOUDS_INITIAL_SPEED; + const float cloudsSpeed = (-CLOUDS_INITIAL_SPEED) + (-CLOUDS_FINAL_SPEED * (static_cast(Stage::total_power) / total_power_to_complete_game_)); background_->setCloudsSpeed(cloudsSpeed); // Calcula la transición de los diferentes fondos @@ -981,6 +982,11 @@ void Game::updateBackground() background_->setGradientNumber(static_cast(gradient_number)); background_->setTransition(percent); + // Calcula la posición del sol + constexpr float sun_final_power = num * 2; + background_->setSunProgression(Stage::total_power / sun_final_power); + background_->setMoonProgression(Stage::total_power / static_cast(total_power_to_complete_game_)); + // Actualiza el objeto background_->update(); } @@ -1690,9 +1696,6 @@ void Game::initDemo(int player_id) // Configura los marcadores scoreboard_->setMode(SCOREBOARD_LEFT_PANEL, ScoreboardMode::DEMO); scoreboard_->setMode(SCOREBOARD_RIGHT_PANEL, ScoreboardMode::DEMO); - - // Añade unos cuantos globos - // balloon_manager_->createRandomBalloons(); } // Modo grabar demo @@ -1931,7 +1934,7 @@ void Game::updateGameStatePlaying() #ifdef DEBUG if (auto_pop_balloons_) { - Stage::addPower(20); + Stage::addPower(5); } #endif updatePlayers();