new: ja es pot començar el joc els dos jugador a l'hora
new: feedback visual per a saber qui ha pulsat start en la pantalla de titol Player: afegit estat RESPAWNING per no tindre que estar fent cabrioles amb la invulnerabilitat al crear als jugadors
This commit is contained in:
@@ -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<Game>(player_id, current_stage, GAME_MODE_DEMO_OFF);
|
||||
auto game = std::make_unique<Game>(player_id, CURRENT_STAGE, GAME_MODE_DEMO_OFF);
|
||||
game->run();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
|
||||
@@ -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<Player>(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<Player>(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<Player>(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<Player>(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<int>(r), static_cast<int>(g), static_cast<int>(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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -927,7 +927,7 @@ void Game::handlePlayerCollision(std::shared_ptr<Player> &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> &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
|
||||
@@ -2076,7 +2081,6 @@ void Game::checkServiceMenu()
|
||||
service_menu_was_active = service_menu_is_active;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
// Comprueba los eventos en el modo DEBUG
|
||||
void Game::checkDebugEvents(const SDL_Event &event)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
// START
|
||||
// Boton START
|
||||
if (Input::get()->checkInput(InputAction::START, INPUT_DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index))
|
||||
{
|
||||
if ((state_ == TitleState::LOGO_FINISHED || ALLOW_TITLE_ANIMATION_SKIP) && !fade_->isEnabled())
|
||||
if ((state_ != TitleState::LOGO_ANIMATING || ALLOW_TITLE_ANIMATION_SKIP))
|
||||
{
|
||||
Audio::get()->playSound("game_start.wav");
|
||||
Audio::get()->fadeOutMusic(1500);
|
||||
switch (CONTROLLER.player_id)
|
||||
if (CONTROLLER.player_id == 1)
|
||||
{
|
||||
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;
|
||||
}
|
||||
state_ = TitleState::START_HAS_BEEN_PRESSED;
|
||||
if (!player1_start_pressed_)
|
||||
{
|
||||
player1_start_pressed_ = true;
|
||||
getPlayer(1)->setPlayingState(PlayerState::TITLE_ANIMATION);
|
||||
setState(TitleState::START_HAS_BEEN_PRESSED);
|
||||
counter_ = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
@@ -396,3 +412,93 @@ void Title::renderCopyright()
|
||||
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<std::vector<std::shared_ptr<Texture>>> player_textures; // Vector con todas las texturas de los jugadores;
|
||||
std::vector<std::vector<std::string>> player_animations; // Vector con las animaciones del jugador
|
||||
|
||||
// Texturas - Player1
|
||||
{
|
||||
std::vector<std::shared_ptr<Texture>> 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<std::shared_ptr<Texture>> 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<Player>(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<Player>(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<Player> 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;
|
||||
}
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
#include <SDL3/SDL_stdinc.h> // Para Uint32
|
||||
#include <memory> // Para unique_ptr, shared_ptr
|
||||
#include <vector>
|
||||
#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<GameLogo> game_logo_; // Logo del juego
|
||||
std::unique_ptr<Sprite> mini_logo_sprite_; // Logo JailGames mini
|
||||
std::unique_ptr<DefineButtons> define_buttons_; // Definición de botones del joystick
|
||||
std::vector<std::shared_ptr<Player>> players_; // Vector de jugadores
|
||||
|
||||
// --- Variables de estado ---
|
||||
int counter_ = 0; // Temporizador para la pantalla de título
|
||||
@@ -66,6 +69,8 @@ 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
|
||||
@@ -79,9 +84,14 @@ private:
|
||||
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 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<Player> getPlayer(int id); // Obtiene un jugador a partir de su "id"
|
||||
};
|
||||
Reference in New Issue
Block a user