diff --git a/source/credits.cpp b/source/credits.cpp index 1ff02c3..74d00c7 100644 --- a/source/credits.cpp +++ b/source/credits.cpp @@ -17,6 +17,7 @@ #include "text.h" // Para Text, TEXT_CENTER, TEXT_SHADOW #include "tiled_bg.h" // Para TiledBG, TiledBGMode #include "utils.h" // Para Color, no_color, shdw_txt_color, Zone +#include "player.h" // Textos constexpr const char TEXT_COPYRIGHT[] = "@2020,2024 JailDesigner"; @@ -28,10 +29,10 @@ Credits::Credits() tiled_bg_(std::make_unique(param.game.game_area.rect, TiledBGMode::DIAGONAL)) { section::name = section::Name::CREDITS; - // balloon_manager_->setPlayArea(param.game.game_area.rect); - const auto r = param.game.game_area.rect; - const int bars = 30; - balloon_manager_->setPlayArea({r.x, r.y + bars, r.w, r.h - bars}); + top_black_rect_ = {play_area_.x, 0, play_area_.w, black_bars_size_}; + bottom_black_rect_ = {play_area_.x, param.game.game_area.rect.h - black_bars_size_, play_area_.w, black_bars_size_}; + balloon_manager_->setPlayArea(play_area_); + initPlayers(); SDL_SetTextureBlendMode(text_texture_, SDL_BLENDMODE_BLEND); fillTextTexture(); JA_PlayMusic(Resource::get()->getMusic("credits.ogg")); @@ -65,8 +66,13 @@ void Credits::update() ticks_ = SDL_GetTicks(); tiled_bg_->update(); balloon_manager_->update(); - updateRects(); + updateTextureDstRects(); throwBalloons(); + for (auto &player : players_) + { + player->update(); + } + updateFinalFade(); Screen::get()->update(); ++counter_; } @@ -81,16 +87,27 @@ void Credits::render() // Limpia la pantalla Screen::get()->clean(); + // Dibuja el fondo, los globos y los jugadores tiled_bg_->render(); balloon_manager_->render(); - SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 255); - SDL_Rect r1 = {0, 0, 320, 30}; - SDL_Rect r2 = {0, 255 - 30, 320, 30}; - SDL_RenderFillRect(Screen::get()->getRenderer(), &r1); - SDL_RenderFillRect(Screen::get()->getRenderer(), &r2); + for (auto const &player : players_) + { + player->render(); + } + + // Dibuja los titulos de credito SDL_RenderCopy(Screen::get()->getRenderer(), text_texture_, &credits_rect_src_, &credits_rect_dst_); SDL_RenderCopy(Screen::get()->getRenderer(), text_texture_, &mini_logo_rect_src_, &mini_logo_rect_dst_); + // Dibuja los rectangulos negros + SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 255); + SDL_RenderFillRect(Screen::get()->getRenderer(), &top_black_rect_); + SDL_RenderFillRect(Screen::get()->getRenderer(), &bottom_black_rect_); + SDL_RenderFillRect(Screen::get()->getRenderer(), &left_black_rect_); + SDL_RenderFillRect(Screen::get()->getRenderer(), &right_black_rect_); + + SDL_RenderCopy(Screen::get()->getRenderer(), text_texture_, &mini_logo_rect_src_, &mini_logo_rect_dst_); + // Vuelca el contenido del renderizador en pantalla Screen::get()->blit(); } @@ -119,9 +136,10 @@ void Credits::checkInput() // Comprueba si se ha pulsado cualquier botón (de los usados para jugar) if (Input::get()->checkAnyButtonPressed()) { - JA_StopMusic(); - section::name = section::Name::LOGO; - return; + // JA_StopMusic(); + // section::name = section::Name::LOGO; + // return; + fading = true; } // Comprueba los inputs que se pueden introducir en cualquier sección del juego @@ -150,7 +168,7 @@ void Credits::fillTextTexture() "JAILDOCTOR"}; const int space_post_title = 3 + text->getCharacterSize(); - const int space_pre_title = text->getCharacterSize() * 3; + const int space_pre_title = text->getCharacterSize() * 4; const int texts_height = 1 * text->getCharacterSize() + 7 * space_post_title + 3 * space_pre_title; credits_rect_dst_.h = credits_rect_src_.h = texts_height; @@ -217,7 +235,7 @@ void Credits::fillTextTexture() } // Actualiza el destino de los rectangulos de las texturas -void Credits::updateRects() +void Credits::updateTextureDstRects() { if (counter_ % 10 == 0) { @@ -242,8 +260,91 @@ void Credits::throwBalloons() balloon_manager_->deploySet(sets.at(index), -50); } - if (counter_ % (speed * 4) == 0) + if (counter_ % (speed * 4) == 0 && counter_ > 0) { balloon_manager_->createPowerBall(); } +} + +// Inicializa los jugadores +void Credits::initPlayers() +{ + std::vector>> player_textures; // Vector con todas las texturas de los jugadores; + std::vector> player_animations; // Vector con las animaciones del jugador + + // Texturas - Player1 + { + std::vector> player_texture; + player_texture.emplace_back(Resource::get()->getTexture("player1.gif")); + player_texture.emplace_back(Resource::get()->getTexture("player1_power.png")); + player_textures.push_back(player_texture); + } + + // Texturas - Player2 + { + std::vector> player_texture; + player_texture.emplace_back(Resource::get()->getTexture("player2.gif")); + player_texture.emplace_back(Resource::get()->getTexture("player2_power.png")); + player_textures.push_back(player_texture); + } + + // Animaciones -- Jugador + { + player_animations.emplace_back(Resource::get()->getAnimation("player.ani")); + player_animations.emplace_back(Resource::get()->getAnimation("player_power.ani")); + } + + // Crea los dos jugadores + constexpr int player_width = 30; + const int y = play_area_.h - player_width; + constexpr bool demo = false; + constexpr int away_distance = 700; + players_.emplace_back(std::make_unique(1, play_area_.x - away_distance - player_width, y, demo, play_area_, player_textures.at(0), player_animations)); + players_.back()->setWalkingState(PlayerState::WALKING_RIGHT); + players_.back()->setPlayingState(PlayerState::CREDITS); + players_.back()->setInvulnerable(false); + + players_.emplace_back(std::make_unique(2, play_area_.x + play_area_.w + away_distance, y, demo, play_area_, player_textures.at(1), player_animations)); + players_.back()->setWalkingState(PlayerState::WALKING_LEFT); + players_.back()->setPlayingState(PlayerState::CREDITS); + players_.back()->setInvulnerable(false); +} + +// Actualiza los rectangulos negros +void Credits::updateBlackRects() +{ + if (top_black_rect_.h != param.game.game_area.center_y - 1 && bottom_black_rect_.y != param.game.game_area.center_y + 1) + { + // Si los rectangulos superior e inferior no han llegado al centro + if (counter_ % 4 == 0) + { + // Incrementa la altura del rectangulo superior + top_black_rect_.h = std::min(top_black_rect_.h + 1, param.game.game_area.center_y - 1); + + // Incrementa la altura y modifica la posición del rectangulo inferior + ++bottom_black_rect_.h; + bottom_black_rect_.y = std::max(bottom_black_rect_.y - 1, param.game.game_area.center_y + 1); + } + } + else + { + // Si los rectangulos superior e inferior han llegado al centro + { + // Incrementa la anchura del rectangulo situado a la izquierda + left_black_rect_.w = std::min(left_black_rect_.w + 4, param.game.game_area.center_x); + + // Incrementa la anchura y modifica la posición del rectangulo situado a la derecha + right_black_rect_.w += 4; + right_black_rect_.x = std::max(right_black_rect_.x - 4, param.game.game_area.center_x); + } + } +} + +// Actualiza el estado de fade +void Credits::updateFinalFade() +{ + if (fading) + { + updateBlackRects(); + } } \ No newline at end of file diff --git a/source/credits.h b/source/credits.h index bbeac45..0dfb8df 100644 --- a/source/credits.h +++ b/source/credits.h @@ -6,6 +6,7 @@ #include "param.h" class BalloonManager; class TiledBG; +class Player; class Credits { @@ -14,15 +15,29 @@ private: std::unique_ptr balloon_manager_; // Objeto para gestionar los globos SDL_Texture *text_texture_; // Textura con el texto std::unique_ptr tiled_bg_; // Objeto para dibujar el mosaico animado de fondo + std::vector> players_; // Vector con los jugadores // Variables - Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa - Uint32 counter_ = 0; // Contador para la lógica de la clase + Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa + Uint32 counter_ = 0; // Contador para la lógica de la clase + int black_bars_size_ = 28; // Tamaño de las barras negras + int mini_logo_final_pos_ = 0; // Ubicación donde se detiene el minilogo + bool fading = false; // Indica si se está realizando el fade final + + // Rectangulos SDL_Rect credits_rect_src_ = param.game.game_area.rect; // Rectangulo con el texto de los créditos (origen) SDL_Rect credits_rect_dst_ = param.game.game_area.rect; // Rectangulo con el texto de los créditos (destino) SDL_Rect mini_logo_rect_src_ = param.game.game_area.rect; // Rectangulo con el mini logo de JailGames y el texto de copyright (origen) SDL_Rect mini_logo_rect_dst_ = param.game.game_area.rect; // Rectangulo con el mini logo de JailGames y el texto de copyright (destino) - int mini_logo_final_pos_ = 0; + SDL_Rect play_area_ = { + param.game.game_area.rect.x, + param.game.game_area.rect.y + black_bars_size_, + param.game.game_area.rect.w, + param.game.game_area.rect.h - black_bars_size_}; // Area visible para los creditos + SDL_Rect top_black_rect_ = {play_area_.x, 0, play_area_.w, black_bars_size_}; // Rectangulo negro superior + SDL_Rect bottom_black_rect_ = {play_area_.x, param.game.game_area.rect.h - black_bars_size_, play_area_.w, black_bars_size_}; // Rectangulo negro inferior + SDL_Rect left_black_rect_ = {play_area_.x, param.game.game_area.center_y - 1, 0, 2}; // Rectangulo negro situado a la izquierda + SDL_Rect right_black_rect_ = {play_area_.x + play_area_.w, param.game.game_area.center_y - 1, 0, 2}; // Rectangulo negro situado a la derecha // Actualiza las variables void update(); @@ -40,11 +55,20 @@ private: void fillTextTexture(); // Actualiza el destino de los rectangulos de las texturas - void updateRects(); + void updateTextureDstRects(); // Tira globos al escenario void throwBalloons(); + // Inicializa los jugadores + void initPlayers(); + + // Actualiza los rectangulos negros + void updateBlackRects(); + + // Actualiza el estado de fade + void updateFinalFade(); + public: // Constructor Credits(); diff --git a/source/player.cpp b/source/player.cpp index c13391a..6244c24 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -222,6 +222,41 @@ void Player::move() setPlayingState(PlayerState::GAME_OVER); break; } + case PlayerState::CREDITS: + { + pos_x_ += vel_x_ / 2.0f; + if (vel_x_ > 0) + { + // setInputPlaying(InputType::RIGHT); + if (pos_x_ > param.game.game_area.rect.w - WIDTH_) + { + pos_x_ = param.game.game_area.rect.w - WIDTH_; + vel_x_ *= -1; + // setInputPlaying(InputType::LEFT); + } + } + else + { + // setInputPlaying(InputType::LEFT); + if (pos_x_ < param.game.game_area.rect.x) + { + pos_x_ = param.game.game_area.rect.x; + vel_x_ *= -1; + // setInputPlaying(InputType::RIGHT); + } + } + + if (pos_x_ > param.game.game_area.center_x - WIDTH_ / 2) + { + setWalkingState(PlayerState::WALKING_LEFT); + } + else + { + setWalkingState(PlayerState::WALKING_RIGHT); + } + shiftSprite(); + break; + } default: break; } @@ -252,6 +287,7 @@ void Player::setAnimation() case PlayerState::PLAYING: case PlayerState::ENTERING_NAME_GAME_COMPLETED: case PlayerState::LEAVING_SCREEN: + case PlayerState::CREDITS: { // Crea cadenas de texto para componer el nombre de la animación const std::string a_walking = walking_state_ == PlayerState::WALKING_STOP ? "stand" : "walk"; @@ -468,6 +504,11 @@ void Player::setPlayingState(PlayerState state) setScoreboardMode(ScoreboardMode::GAME_COMPLETED); break; } + case PlayerState::CREDITS: + { + vel_x_ = (walking_state_ == PlayerState::WALKING_RIGHT) ? BASE_SPEED_ : -BASE_SPEED_; + break; + } default: break; } diff --git a/source/player.h b/source/player.h index d97d457..ee7a409 100644 --- a/source/player.h +++ b/source/player.h @@ -40,6 +40,7 @@ enum class PlayerState CELEBRATING, // Poniendo pose de victoria ENTERING_NAME_GAME_COMPLETED, // Poniendo nombre en el tramo final del juego LEAVING_SCREEN, // Moviendose fuera de la pantalla + CREDITS, // Estado para los creditos del juego }; // Clase Player