diff --git a/source/director.cpp b/source/director.cpp index 689c72d..6a3512b 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -563,13 +563,33 @@ void Director::runTitle() // Ejecuta la sección donde se juega al juego void Director::runGame() { - const auto player_id = Section::options == Section::Options::GAME_PLAY_1P ? 1 : 2; + int player_id = 1; + + switch (Section::options) + { + case Section::Options::GAME_PLAY_1P: + player_id = 1; + break; + + case Section::Options::GAME_PLAY_2P: + player_id = 2; + break; + + case Section::Options::GAME_PLAY_BOTH: + player_id = 0; + break; + + default: + player_id = 1; + break; + } + #ifdef DEBUG - constexpr auto current_stage = 0; + constexpr int CURRENT_STAGE = 0; #else - constexpr auto current_stage = 0; + constexpr int CURRENT_STAGE = 0; #endif - auto game = std::make_unique(player_id, current_stage, GAME_MODE_DEMO_OFF); + auto game = std::make_unique(player_id, CURRENT_STAGE, GAME_MODE_DEMO_OFF); game->run(); } diff --git a/source/player.cpp b/source/player.cpp index de1e265..a01bce6 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -33,6 +33,8 @@ Player::Player(int id, float x, int y, bool demo, SDL_FRect &play_area, std::vec // Inicializa variables pos_x_ = default_pos_x_; + invulnerable_ = false; + invulnerable_counter_ = 0; init(); } @@ -44,8 +46,6 @@ void Player::init() walking_state_ = PlayerState::WALKING_STOP; firing_state_ = PlayerState::FIRING_NONE; playing_state_ = PlayerState::WAITING; - invulnerable_ = true; - invulnerable_counter_ = INVULNERABLE_COUNTER_; power_up_ = false; power_up_counter_ = POWERUP_COUNTER_; extra_hit_ = false; @@ -177,9 +177,9 @@ void Player::move() shiftSprite(); break; } - case PlayerState::DYING: + case PlayerState::ROLLING: { - // Si el cadaver abandona el area de juego por los laterales lo hace rebotar + // Si el jugador abandona el area de juego por los laterales lo hace rebotar const int X = player_sprite_->getPosX(); const int MIN_X = play_area_.x; const int MAX_X = play_area_.x + play_area_.w - WIDTH_; @@ -190,7 +190,7 @@ void Player::move() playSound("jump.wav"); } - // Si el cadaver toca el suelo rebota y si tiene poca velocidad, se detiene y cambia de estado + // Si el jugador toca el suelo rebota y si tiene poca velocidad, se detiene y cambia de estado if (player_sprite_->getPosY() > play_area_.h - HEIGHT_) { if (player_sprite_->getVelY() < 2.0f) @@ -215,6 +215,24 @@ void Player::move() } break; } + case PlayerState::TITLE_ANIMATION: + { + // Si el jugador abandona el area de juego por los laterales lo detiene + const int X = player_sprite_->getPosX(); + const int MIN_X = play_area_.x - WIDTH_; + const int MAX_X = play_area_.x + play_area_.w; + if ((X < MIN_X) || (X > MAX_X)) + { + setPlayingState(PlayerState::TITLE_HIDDEN); + } + + // Si el jugador toca el suelo rebota lo detiene + if (player_sprite_->getPosY() > play_area_.h) + { + setPlayingState(PlayerState::TITLE_HIDDEN); + } + break; + } case PlayerState::CONTINUE_TIME_OUT: { // Si el cadaver desaparece por el suelo, cambia de estado @@ -397,8 +415,9 @@ void Player::setAnimation() } break; } - case PlayerState::DYING: + case PlayerState::ROLLING: case PlayerState::CONTINUE_TIME_OUT: + case PlayerState::TITLE_ANIMATION: { player_sprite_->setCurrentAnimation("rolling"); break; @@ -562,6 +581,13 @@ void Player::setPlayingState(PlayerState state) switch (playing_state_) { + case PlayerState::RESPAWNING: + { + setInvulnerable(true); + addCredit(); + playSound("voice_thankyou.wav"); + setPlayingState(PlayerState::PLAYING); + } case PlayerState::PLAYING: { init(); @@ -597,14 +623,28 @@ void Player::setPlayingState(PlayerState state) addScoreToScoreBoard(); break; } - case PlayerState::DYING: + case PlayerState::ROLLING: { - // Activa la animación de morir + // Activa la animación de rodar player_sprite_->setAccelY(0.2f); player_sprite_->setVelY(-6.6f); (rand() % 2 == 0) ? player_sprite_->setVelX(3.3f) : player_sprite_->setVelX(-3.3f); break; } + case PlayerState::TITLE_ANIMATION: + { + // Activa la animación de rodar + player_sprite_->setAccelY(0.2f); + player_sprite_->setVelY(-6.6f); + playSound("voice_thankyou.wav"); + break; + } + case PlayerState::TITLE_HIDDEN: + { + player_sprite_->setVelX(0.0f); + player_sprite_->setVelY(0.0f); + break; + } case PlayerState::CONTINUE_TIME_OUT: { // Activa la animación de morir diff --git a/source/player.h b/source/player.h index 9ea852f..2ae94ee 100644 --- a/source/player.h +++ b/source/player.h @@ -38,14 +38,14 @@ enum class PlayerState COOLING_LEFT, // Enfriando tras disparar hacia la izquierda COOLING_RIGHT, // Enfriando tras disparar hacia la derecha - // Estados generales de juego + // Estados generales del jugador PLAYING, // Está jugando activamente CONTINUE, // Cuenta atrás para continuar tras perder CONTINUE_TIME_OUT, // Se ha terminado la cuenta atras para continuar y se retira al jugador de la zona de juego WAITING, // Esperando para entrar a jugar ENTERING_NAME, // Introduciendo nombre para la tabla de puntuaciones SHOWING_NAME, // Mostrando el nombre introducido - DYING, // El jugador está muriendo (animación de muerte) + ROLLING, // El jugador está muriendo (animación de muerte) LYING_ON_THE_FLOOR_FOREVER, // El jugador está inconsciente para siempre en el suelo (demo) GAME_OVER, // Fin de la partida, no puede jugar CELEBRATING, // Celebrando victoria (pose de victoria) @@ -53,6 +53,9 @@ enum class PlayerState LEAVING_SCREEN, // Saliendo de la pantalla (animación) ENTERING_SCREEN, // Entrando a la pantalla (animación) CREDITS, // Estado para mostrar los créditos del juego + TITLE_ANIMATION, // Animacion para el titulo + TITLE_HIDDEN, // Animacion para el titulo + RESPAWNING, // Tras continuar y volver al juego }; // --- Clase Player --- @@ -104,7 +107,7 @@ public: bool isLyingOnTheFloorForever() const { return playing_state_ == PlayerState::LYING_ON_THE_FLOOR_FOREVER; } bool isCelebrating() const { return playing_state_ == PlayerState::CELEBRATING; } bool isContinue() const { return playing_state_ == PlayerState::CONTINUE; } - bool isDying() const { return playing_state_ == PlayerState::DYING; } + bool isDying() const { return playing_state_ == PlayerState::ROLLING; } bool isEnteringName() const { return playing_state_ == PlayerState::ENTERING_NAME; } bool isShowingName() const { return playing_state_ == PlayerState::SHOWING_NAME; } bool isEnteringNameGameCompleted() const { return playing_state_ == PlayerState::ENTERING_NAME_GAME_COMPLETED; } @@ -112,6 +115,7 @@ public: bool isGameOver() const { return playing_state_ == PlayerState::GAME_OVER; } bool isPlaying() const { return playing_state_ == PlayerState::PLAYING; } bool isWaiting() const { return playing_state_ == PlayerState::WAITING; } + bool isTitleHidden() const { return playing_state_ == PlayerState::TITLE_HIDDEN; } // Getters bool canFire() const { return cant_fire_counter_ <= 0; } @@ -222,6 +226,6 @@ private: void updateScoreboard(); // Actualiza el panel del marcador void setScoreboardMode(ScoreboardMode mode); // Cambia el modo del marcador void playSound(const std::string &name); // Hace sonar un sonido - bool isRenderable() const { return !isWaiting() && !isGameOver(); } + bool isRenderable() const { return !isWaiting() && !isGameOver() && !isTitleHidden(); } void addScoreToScoreBoard(); // Añade una puntuación a la tabla de records }; \ No newline at end of file diff --git a/source/section.h b/source/section.h index 7d816b6..f88e597 100644 --- a/source/section.h +++ b/source/section.h @@ -26,8 +26,9 @@ namespace Section // --- Opciones para la sección actual --- enum class Options { - GAME_PLAY_1P, // Jugar 1 jugador - GAME_PLAY_2P, // Jugar 2 jugadores + GAME_PLAY_1P, // Iniciar el juego con el jugador 1 + GAME_PLAY_2P, // Iniciar el juego con el jugador 2 + GAME_PLAY_BOTH, // Iniciar el juego con los dos jugadores TITLE_TIME_OUT, // Timeout en el título TITLE_1, // Opción 1 en el título TITLE_2, // Opción 2 en el título diff --git a/source/sections/credits.cpp b/source/sections/credits.cpp index 9145908..5443f2c 100644 --- a/source/sections/credits.cpp +++ b/source/sections/credits.cpp @@ -102,10 +102,7 @@ void Credits::update() balloon_manager_->update(); updateTextureDstRects(); throwBalloons(); - for (auto &player : players_) - { - player->update(); - } + updatePlayers(); updateAllFades(); ++counter_; } @@ -254,10 +251,7 @@ void Credits::fillCanvas() // Dibuja el fondo, los globos y los jugadores tiled_bg_->render(); balloon_manager_->render(); - for (auto const &player : players_) - { - player->render(); - } + renderPlayers(); // Dibuja los titulos de credito SDL_RenderTexture(Screen::get()->getRenderer(), text_texture_, &credits_rect_src_, &credits_rect_dst_); @@ -381,19 +375,17 @@ void Credits::initPlayers() } // Crea los dos jugadores - constexpr int player_width = 30; - const int y = play_area_.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)); + constexpr int PLAYER_WIDTH = 32; + const int Y = play_area_.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_.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 @@ -532,3 +524,21 @@ void Credits::cycleColors() // Aplicar el color, redondeando a enteros antes de usar tiled_bg_->setColor(Color(static_cast(r), static_cast(g), static_cast(b))); } + +// Actualza los jugadores +void Credits::updatePlayers() +{ + for (auto &player : players_) + { + player->update(); + } +} + +// Renderiza los jugadores +void Credits::renderPlayers() +{ + for (auto const &player : players_) + { + player->render(); + } +} diff --git a/source/sections/credits.h b/source/sections/credits.h index 3e2234a..da13fed 100644 --- a/source/sections/credits.h +++ b/source/sections/credits.h @@ -58,7 +58,7 @@ private: // --- Control de audio --- int initial_volume_ = Options::audio.music.volume; // Volumen inicial - int steps_ = 0; // Pasos para reducir audio + int steps_ = 0; // Pasos para reducir audio // --- Rectángulos de renderizado --- // Texto de créditos @@ -111,12 +111,14 @@ private: void fillTextTexture(); // Crear textura de texto de créditos void fillCanvas(); // Renderizar todos los sprites y fondos void updateTextureDstRects(); // Actualizar destinos de texturas + void renderPlayers(); // Renderiza los jugadores // --- Métodos de lógica del juego --- void throwBalloons(); // Lanzar globos al escenario void initPlayers(); // Inicializar jugadores void updateAllFades(); // Actualizar estados de fade void cycleColors(); // Cambiar colores de fondo + void updatePlayers(); // Actualza los jugadores // --- Métodos de interfaz --- void updateBlackRects(); // Actualizar rectángulos negros (letterbox) diff --git a/source/sections/game.cpp b/source/sections/game.cpp index 99d3f6f..66a259f 100644 --- a/source/sections/game.cpp +++ b/source/sections/game.cpp @@ -927,7 +927,7 @@ void Game::handlePlayerCollision(std::shared_ptr &player) playSound("player_collision.wav"); screen_->shake(); playSound("voice_no.wav"); - player->setPlayingState(PlayerState::DYING); + player->setPlayingState(PlayerState::ROLLING); players_to_reorder.push_back(player); if (allPlayersAreNotPlaying()) { @@ -1586,9 +1586,7 @@ void Game::handlePlayerContinue(const std::shared_ptr &player) const auto controllerIndex = player->getController(); if (input_->checkInput(InputAction::START, INPUT_DO_NOT_ALLOW_REPEAT, Options::controllers[controllerIndex].type, Options::controllers[controllerIndex].index)) { - player->setPlayingState(PlayerState::PLAYING); - player->addCredit(); - playSound("voice_thankyou.wav"); + player->setPlayingState(PlayerState::RESPAWNING); } // Disminuye el contador de continuación si se presiona cualquier botón de disparo. @@ -1799,10 +1797,17 @@ void Game::initPlayers(int player_id) players_.back()->setName(Lang::getText("[SCOREBOARD] 2")); players_.back()->setController(getController(players_.back()->getId())); - // Activa el jugador que coincide con el "player_id" - auto player = getPlayer(player_id); - player->setPlayingState((demo_.enabled) ? PlayerState::PLAYING : PlayerState::ENTERING_SCREEN); - player->setInvulnerable(false); + // Activa el jugador que coincide con el "player_id" o ambos si es "0" + if (player_id == 0) + { + // Activa ambos jugadores + getPlayer(1)->setPlayingState(demo_.enabled ? PlayerState::PLAYING : PlayerState::ENTERING_SCREEN); + getPlayer(2)->setPlayingState(demo_.enabled ? PlayerState::PLAYING : PlayerState::ENTERING_SCREEN); + } + else + { + getPlayer(player_id)->setPlayingState(demo_.enabled ? PlayerState::PLAYING : PlayerState::ENTERING_SCREEN); + } } // Hace sonar la música @@ -2053,30 +2058,29 @@ void Game::movePlayersToFront() // Comprueba si está activo el menu de servicio para poner el juego en pausa void Game::checkServiceMenu() { - if (demo_.enabled) - return; + if (demo_.enabled) + return; - static bool was_paused_before_service_menu = false; - static bool service_menu_was_active = false; + static bool was_paused_before_service_menu = false; + static bool service_menu_was_active = false; - bool service_menu_is_active = ServiceMenu::get()->isEnabled(); + bool service_menu_is_active = ServiceMenu::get()->isEnabled(); - if (service_menu_is_active && !service_menu_was_active) - { - // El menú acaba de abrirse - was_paused_before_service_menu = paused_; - pause(true); - } - else if (!service_menu_is_active && service_menu_was_active) - { - // El menú acaba de cerrarse - pause(was_paused_before_service_menu); - } + if (service_menu_is_active && !service_menu_was_active) + { + // El menú acaba de abrirse + was_paused_before_service_menu = paused_; + pause(true); + } + else if (!service_menu_is_active && service_menu_was_active) + { + // El menú acaba de cerrarse + pause(was_paused_before_service_menu); + } - service_menu_was_active = service_menu_is_active; + service_menu_was_active = service_menu_is_active; } - #ifdef DEBUG // Comprueba los eventos en el modo DEBUG void Game::checkDebugEvents(const SDL_Event &event) diff --git a/source/sections/title.cpp b/source/sections/title.cpp index b861561..0e07bb9 100644 --- a/source/sections/title.cpp +++ b/source/sections/title.cpp @@ -16,6 +16,7 @@ #include "notifier.h" // Para Notifier #include "options.h" // Para OptionsController, Options, options #include "param.h" // Para Param, param, ParamGame, ParamTitle +#include "player.h" // Para Player, PlayerState #include "resource.h" // Para Resource #include "screen.h" // Para Screen #include "section.h" // Para Options, Name, name, AttractMode, options @@ -43,6 +44,7 @@ Title::Title() fade_->setColor(param.fade.color); fade_->setType(FadeType::RANDOM_SQUARE); fade_->setPostDuration(param.fade.post_duration); + initPlayers(); // Asigna valores a otras variables Section::options = Section::Options::TITLE_1; @@ -75,6 +77,7 @@ void Title::update() updateFade(); updateState(); updateStartPrompt(); + updatePlayers(); Screen::get()->update(); } } @@ -89,6 +92,7 @@ void Title::render() game_logo_->render(); renderStartPrompt(); renderCopyright(); + renderPlayers(); define_buttons_->render(); fade_->render(); @@ -144,38 +148,42 @@ void Title::checkEvents() // Comprueba las entradas void Title::checkInput() { + // Comprueba las entradas solo si no se estan definiendo los botones + if (define_buttons_->isEnabled()) + return; + Input::get()->update(); if (!ServiceMenu::get()->isEnabled()) { - // Comprueba las entradas solo si no se estan definiendo los botones - if (!define_buttons_->isEnabled()) + // Comprueba todos los métodos de control + for (const auto &CONTROLLER : Options::controllers) { - // Comprueba todos los métodos de control - for (const auto &CONTROLLER : Options::controllers) + // Boton START + if (Input::get()->checkInput(InputAction::START, INPUT_DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { - // START - if (Input::get()->checkInput(InputAction::START, INPUT_DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) + if ((state_ != TitleState::LOGO_ANIMATING || ALLOW_TITLE_ANIMATION_SKIP)) { - if ((state_ == TitleState::LOGO_FINISHED || ALLOW_TITLE_ANIMATION_SKIP) && !fade_->isEnabled()) + if (CONTROLLER.player_id == 1) { - Audio::get()->playSound("game_start.wav"); - Audio::get()->fadeOutMusic(1500); - switch (CONTROLLER.player_id) + if (!player1_start_pressed_) { - case 1: - selection_ = Section::Options::GAME_PLAY_1P; - break; - case 2: - selection_ = Section::Options::GAME_PLAY_2P; - break; - default: - selection_ = Section::Options::TITLE_TIME_OUT; - break; + player1_start_pressed_ = true; + getPlayer(1)->setPlayingState(PlayerState::TITLE_ANIMATION); + setState(TitleState::START_HAS_BEEN_PRESSED); + counter_ = 0; + } + } + + if (CONTROLLER.player_id == 2) + { + if (!player2_start_pressed_) + { + player2_start_pressed_ = true; + getPlayer(2)->setPlayingState(PlayerState::TITLE_ANIMATION); + setState(TitleState::START_HAS_BEEN_PRESSED); + counter_ = 0; } - state_ = TitleState::START_HAS_BEEN_PRESSED; - counter_ = 0; - return; } } } @@ -183,10 +191,7 @@ void Title::checkInput() } // Comprueba los inputs que se pueden introducir en cualquier sección del juego - if (!define_buttons_->isEnabled()) - { - GlobalInputs::check(); - } + GlobalInputs::check(); } // Bucle para el titulo del juego @@ -208,9 +213,7 @@ void Title::resetCounter() { counter_ = 0; } void Title::swapControllers() { if (Input::get()->getNumControllers() == 0) - { return; - } Options::swapControllers(); showControllers(); @@ -259,17 +262,31 @@ void Title::updateFade() fade_->update(); if (fade_->hasEnded()) { - if (selection_ == Section::Options::TITLE_TIME_OUT) + const int COMBO = (player1_start_pressed_ ? 1 : 0) | (player2_start_pressed_ ? 2 : 0); + + switch (COMBO) { - // El menu ha hecho time out + case 0: // Ningún jugador ha pulsado Start Section::name = next_section_; - } - else - { - // Se ha pulsado para jugar + break; + + case 1: // Solo el jugador 1 ha pulsado Start Section::name = Section::Name::GAME; - Section::options = selection_; + Section::options = Section::Options::GAME_PLAY_1P; Audio::get()->stopMusic(); + break; + + case 2: // Solo el jugador 2 ha pulsado Start + Section::name = Section::Name::GAME; + Section::options = Section::Options::GAME_PLAY_2P; + Audio::get()->stopMusic(); + break; + + case 3: // Ambos jugadores han pulsado Start + Section::name = Section::Name::GAME; + Section::options = Section::Options::GAME_PLAY_BOTH; + Audio::get()->stopMusic(); + break; } } } @@ -285,8 +302,7 @@ void Title::updateState() game_logo_->update(); if (game_logo_->hasFinished()) { - state_ = TitleState::LOGO_FINISHED; - Audio::get()->playMusic("title.ogg"); + setState(TitleState::LOGO_FINISHED); } break; } @@ -395,4 +411,94 @@ void Title::renderCopyright() 1, TITLE_SHADOW_TEXT_COLOR); } +} + +// Cambia el estado +void Title::setState(TitleState state) +{ + if (state_ == state) + return; + + state_ = state; + switch (state_) + { + case TitleState::LOGO_ANIMATING: + break; + case TitleState::LOGO_FINISHED: + Audio::get()->playMusic("title.ogg"); + break; + case TitleState::START_HAS_BEEN_PRESSED: + Audio::get()->fadeOutMusic(1500); + break; + } +} + +// Inicializa los jugadores +void Title::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 = 32; + const int Y = param.title.press_start_position; + constexpr bool DEMO = false; + players_.emplace_back(std::make_unique(1, param.game.game_area.first_quarter_x - (PLAYER_WIDTH / 2), Y, DEMO, param.game.play_area.rect, player_textures.at(0), player_animations)); + players_.back()->setPlayingState(PlayerState::TITLE_HIDDEN); + + players_.emplace_back(std::make_unique(2, param.game.game_area.third_quarter_x - (PLAYER_WIDTH / 2), Y, DEMO, param.game.play_area.rect, player_textures.at(1), player_animations)); + players_.back()->setPlayingState(PlayerState::TITLE_HIDDEN); +} + +// Actualza los jugadores +void Title::updatePlayers() +{ + for (auto &player : players_) + { + player->update(); + } +} + +// Renderiza los jugadores +void Title::renderPlayers() +{ + for (auto const &player : players_) + { + player->render(); + } +} + +// Obtiene un jugador a partir de su "id" +std::shared_ptr Title::getPlayer(int id) +{ + auto it = std::find_if(players_.begin(), players_.end(), [id](const auto &player) + { return player->getId() == id; }); + + if (it != players_.end()) + { + return *it; + } + return nullptr; } \ No newline at end of file diff --git a/source/sections/title.h b/source/sections/title.h index 2043a7f..a3bcac2 100644 --- a/source/sections/title.h +++ b/source/sections/title.h @@ -2,11 +2,13 @@ #include // Para Uint32 #include // Para unique_ptr, shared_ptr -#include "section.h" // Para Options +#include +#include "section.h" // Para Options class DefineButtons; class Fade; class GameLogo; +class Player; class Sprite; class Text; class TiledBG; @@ -57,6 +59,7 @@ private: std::unique_ptr game_logo_; // Logo del juego std::unique_ptr mini_logo_sprite_; // Logo JailGames mini std::unique_ptr define_buttons_; // Definición de botones del joystick + std::vector> players_; // Vector de jugadores // --- Variables de estado --- int counter_ = 0; // Temporizador para la pantalla de título @@ -66,22 +69,29 @@ private: int num_controllers_; // Número de mandos conectados TitleState state_; // Estado actual de la sección bool should_render_start_prompt = false; // Indica si se muestra o no el texto de PRESS START BUTTON TO PLAY + bool player1_start_pressed_ = false; // Indica si se ha pulsdo el boton de empezar a jugar para el jugador 1 + bool player2_start_pressed_ = false; // Indica si se ha pulsdo el boton de empezar a jugar para el jugador 2 // -- Variables de diseño --- Anchor anchor_; // Anclas para definir la posición de los elementos del titulo // --- Métodos internos --- - void update(); // Actualiza las variables del objeto - void render(); // Dibuja el objeto en pantalla - void checkEvents(); // Comprueba los eventos - void checkInput(); // Comprueba las entradas - void resetCounter(); // Reinicia el contador interno - void swapControllers(); // Intercambia la asignación de mandos a los jugadores - void swapKeyboard(); // Intercambia el teclado de jugador - void showControllers(); // Muestra información sobre los controles y los jugadores - void updateFade(); // Actualiza el fade - void updateState(); // Actualiza el estado - void updateStartPrompt(); - void renderStartPrompt(); - void renderCopyright(); + void update(); // Actualiza las variables del objeto + void render(); // Dibuja el objeto en pantalla + void checkEvents(); // Comprueba los eventos + void checkInput(); // Comprueba las entradas + void resetCounter(); // Reinicia el contador interno + void swapControllers(); // Intercambia la asignación de mandos a los jugadores + void swapKeyboard(); // Intercambia el teclado de jugador + void showControllers(); // Muestra información sobre los controles y los jugadores + void updateFade(); // Actualiza el efecto de fundido (fade in/out) + void updateState(); // Actualiza el estado actual del título + void updateStartPrompt(); // Actualiza el mensaje de "Pulsa Start" + void renderStartPrompt(); // Dibuja el mensaje de "Pulsa Start" en pantalla + void renderCopyright(); // Dibuja el aviso de copyright + void setState(TitleState state); // Cambia el estado del título + void initPlayers(); // Inicializa los jugadores + void renderPlayers(); // Renderiza los jugadores + void updatePlayers(); // Actualza los jugadores + std::shared_ptr getPlayer(int id); // Obtiene un jugador a partir de su "id" }; \ No newline at end of file