afegit pause_manager
This commit is contained in:
129
source/pause_manager.h
Normal file
129
source/pause_manager.h
Normal file
@@ -0,0 +1,129 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
// Clase dedicada para manejar el sistema de pausa
|
||||
class PauseManager {
|
||||
public:
|
||||
// Enum encapsulado dentro de la clase
|
||||
enum class Source : uint8_t {
|
||||
NONE = 0,
|
||||
PLAYER = 1 << 0, // 0001
|
||||
SERVICE_MENU = 1 << 1, // 0010
|
||||
FOCUS_LOST = 1 << 2 // 0100
|
||||
};
|
||||
|
||||
// Operadores para trabajar con las banderas (funciones friend)
|
||||
friend Source operator|(Source a, Source b) {
|
||||
return static_cast<Source>(static_cast<uint8_t>(a) | static_cast<uint8_t>(b));
|
||||
}
|
||||
|
||||
friend Source operator&(Source a, Source b) {
|
||||
return static_cast<Source>(static_cast<uint8_t>(a) & static_cast<uint8_t>(b));
|
||||
}
|
||||
|
||||
friend Source operator~(Source a) {
|
||||
return static_cast<Source>(~static_cast<uint8_t>(a));
|
||||
}
|
||||
|
||||
friend Source& operator|=(Source& a, Source b) {
|
||||
return a = a | b;
|
||||
}
|
||||
|
||||
friend Source& operator&=(Source& a, Source b) {
|
||||
return a = a & b;
|
||||
}
|
||||
|
||||
private:
|
||||
Source flags_ = Source::NONE;
|
||||
std::function<void(bool)> onPauseChangedCallback_;
|
||||
|
||||
bool hasFlag(Source flag) const {
|
||||
return (flags_ & flag) != Source::NONE;
|
||||
}
|
||||
|
||||
void notifyPauseChanged() {
|
||||
if (onPauseChangedCallback_) {
|
||||
onPauseChangedCallback_(isPaused());
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
// Constructor con callback opcional
|
||||
explicit PauseManager(std::function<void(bool)> callback = nullptr)
|
||||
: onPauseChangedCallback_(callback) {}
|
||||
|
||||
// Establece/quita una fuente de pausa específica
|
||||
void setFlag(Source source, bool enable) {
|
||||
bool wasPaused = isPaused();
|
||||
|
||||
if (enable) {
|
||||
flags_ |= source;
|
||||
} else {
|
||||
flags_ &= ~source;
|
||||
}
|
||||
|
||||
// Solo notifica si cambió el estado general de pausa
|
||||
if (wasPaused != isPaused()) {
|
||||
notifyPauseChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// Métodos específicos para cada fuente
|
||||
void setPlayerPause(bool enable) { setFlag(Source::PLAYER, enable); }
|
||||
void setServiceMenuPause(bool enable) { setFlag(Source::SERVICE_MENU, enable); }
|
||||
void setFocusLossPause(bool enable) { setFlag(Source::FOCUS_LOST, enable); }
|
||||
|
||||
// Toggle para el jugador (más común)
|
||||
void togglePlayerPause() { setPlayerPause(!isPlayerPaused()); }
|
||||
|
||||
// Getters
|
||||
bool isPaused() const { return flags_ != Source::NONE; }
|
||||
bool isPlayerPaused() const { return hasFlag(Source::PLAYER); }
|
||||
bool isServiceMenuPaused() const { return hasFlag(Source::SERVICE_MENU); }
|
||||
bool isFocusLossPaused() const { return hasFlag(Source::FOCUS_LOST); }
|
||||
|
||||
// Obtiene las banderas actuales
|
||||
Source getFlags() const { return flags_; }
|
||||
|
||||
// Limpia todas las pausas (útil para reset)
|
||||
void clearAll() {
|
||||
if (isPaused()) {
|
||||
flags_ = Source::NONE;
|
||||
notifyPauseChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// Método para debug
|
||||
std::string getStatusString() const {
|
||||
if (flags_ == Source::NONE) return "Active";
|
||||
|
||||
std::string result = "Paused by: ";
|
||||
bool first = true;
|
||||
|
||||
if (hasFlag(Source::PLAYER)) {
|
||||
if (!first) result += ", ";
|
||||
result += "Player";
|
||||
first = false;
|
||||
}
|
||||
if (hasFlag(Source::SERVICE_MENU)) {
|
||||
if (!first) result += ", ";
|
||||
result += "ServiceMenu";
|
||||
first = false;
|
||||
}
|
||||
if (hasFlag(Source::FOCUS_LOST)) {
|
||||
if (!first) result += ", ";
|
||||
result += "FocusLoss";
|
||||
first = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Permite cambiar el callback en runtime
|
||||
void setCallback(std::function<void(bool)> callback) {
|
||||
onPauseChangedCallback_ = callback;
|
||||
}
|
||||
};
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "manage_hiscore_table.h" // Para HiScoreEntry, ManageHiScoreTable
|
||||
#include "param.h" // Para Param, param, ParamGame, ParamScoreboard, ParamFade, ParamBalloon
|
||||
#include "path_sprite.h" // Para Path, PathSprite, createPath, PathType
|
||||
#include "pause_manager.h" // Para PauseManager
|
||||
#include "player.h" // Para Player
|
||||
#include "resource.h" // Para Resource
|
||||
#include "scoreboard.h" // Para Scoreboard
|
||||
@@ -50,6 +51,7 @@ Game::Game(Player::Id player_id, int current_stage, bool demo)
|
||||
input_(Input::get()),
|
||||
background_(std::make_unique<Background>()),
|
||||
canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.play_area.rect.w, param.game.play_area.rect.h)),
|
||||
pause_manager_(std::make_unique<PauseManager>([this](bool isPaused) { onPauseStateChanged(isPaused); })),
|
||||
fade_in_(std::make_unique<Fade>()),
|
||||
fade_out_(std::make_unique<Fade>()),
|
||||
balloon_manager_(std::make_unique<BalloonManager>()),
|
||||
@@ -914,7 +916,7 @@ void Game::render() {
|
||||
|
||||
// Actualiza los estados del juego
|
||||
void Game::updateGameStates() {
|
||||
if (!paused_) {
|
||||
if (!pause_manager_->isPaused()) {
|
||||
switch (state_) {
|
||||
case State::FADE_IN:
|
||||
updateGameStateFadeIn();
|
||||
@@ -1121,11 +1123,11 @@ void Game::checkEvents() {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_EVENT_WINDOW_FOCUS_LOST: {
|
||||
pause(!demo_.enabled);
|
||||
pause_manager_->setFocusLossPause(!demo_.enabled);
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_FOCUS_GAINED: {
|
||||
pause(false);
|
||||
pause_manager_->setFocusLossPause(false);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -1156,13 +1158,6 @@ void Game::updateScoreboard() {
|
||||
scoreboard_->update();
|
||||
}
|
||||
|
||||
// Pausa el juego
|
||||
void Game::pause(bool value) {
|
||||
paused_ = value;
|
||||
screen_->attenuate(paused_);
|
||||
tabe_->pauseTimer(paused_);
|
||||
}
|
||||
|
||||
// Añade una puntuación a la tabla de records
|
||||
void Game::addScoreToScoreBoard(const std::shared_ptr<Player> &player) {
|
||||
const auto ENTRY = HiScoreEntry(trim(player->getLastEnterName()), player->getScore(), player->get1CC());
|
||||
@@ -1242,17 +1237,16 @@ void Game::checkInput() {
|
||||
// Verifica si alguno de los controladores ha solicitado una pausa y actualiza el estado de pausa del juego.
|
||||
void Game::checkPauseInput() {
|
||||
// Comprueba los mandos
|
||||
auto gamepads = input_->getGamepads();
|
||||
for (auto gamepad : gamepads) {
|
||||
for (auto gamepad : input_->getGamepads()) {
|
||||
if (input_->checkAction(Input::Action::PAUSE, Input::DO_NOT_ALLOW_REPEAT, Input::DO_NOT_CHECK_KEYBOARD, gamepad)) {
|
||||
pause(!paused_);
|
||||
pause_manager_->togglePlayerPause();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Comprueba el teclado
|
||||
if (input_->checkAction(Input::Action::PAUSE, Input::DO_NOT_ALLOW_REPEAT, Input::CHECK_KEYBOARD)) {
|
||||
pause(!paused_);
|
||||
pause_manager_->togglePlayerPause();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1872,21 +1866,11 @@ void Game::checkServiceMenu() {
|
||||
return;
|
||||
}
|
||||
|
||||
static bool was_paused_before_service_menu_ = false;
|
||||
static bool service_menu_was_active_ = false;
|
||||
|
||||
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 (ServiceMenu::get()->isEnabled()) {
|
||||
pause_manager_->setServiceMenuPause(true);
|
||||
} else {
|
||||
pause_manager_->setServiceMenuPause(false);
|
||||
}
|
||||
|
||||
service_menu_was_active_ = service_menu_is_active;
|
||||
}
|
||||
|
||||
// Mueve el jugador para pintarlo al fondo de la lista de jugadores
|
||||
@@ -1899,6 +1883,11 @@ void Game::sendPlayerToTheFront(const std::shared_ptr<Player> &player) {
|
||||
players_to_put_at_front_.push_back(player);
|
||||
}
|
||||
|
||||
void Game::onPauseStateChanged(bool isPaused) {
|
||||
screen_->attenuate(isPaused);
|
||||
tabe_->pauseTimer(isPaused);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Comprueba los eventos en el modo DEBUG
|
||||
void Game::checkDebugEvents(const SDL_Event &event) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <SDL3/SDL.h> // Para SDL_Event, SDL_Renderer, SDL_Texture, Uint64, Uint8
|
||||
|
||||
#include <memory> // Para shared_ptr, unique_ptr
|
||||
#include <set> // Para Set
|
||||
#include <string> // Para string
|
||||
#include <vector> // Para vector
|
||||
|
||||
@@ -11,6 +12,7 @@
|
||||
#include "manage_hiscore_table.h" // Para HiScoreEntry
|
||||
#include "options.h" // Para SettingsOptions, settings
|
||||
#include "path_sprite.h" // Para PathSprite, Path
|
||||
#include "pause_manager.h" // Para PauseManager
|
||||
#include "player.h" // Para Player
|
||||
#include "smart_sprite.h" // Para SmartSprite
|
||||
#include "utils.h" // Para Demo
|
||||
@@ -116,6 +118,7 @@ class Game {
|
||||
std::vector<std::vector<std::string>> item_animations_; // Vector con las animaciones de los items
|
||||
std::vector<std::vector<std::string>> player_animations_; // Vector con las animaciones del jugador
|
||||
|
||||
std::unique_ptr<PauseManager> pause_manager_; // Objeto para gestionar la pausa
|
||||
std::unique_ptr<Fade> fade_in_; // Objeto para renderizar fades
|
||||
std::unique_ptr<Fade> fade_out_; // Objeto para renderizar fades
|
||||
std::unique_ptr<BalloonManager> balloon_manager_; // Objeto para gestionar los globos
|
||||
@@ -133,8 +136,6 @@ class Game {
|
||||
Uint64 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
||||
bool coffee_machine_enabled_ = false; // Indica si hay una máquina de café en el terreno de juego
|
||||
bool hi_score_achieved_ = false; // Indica si se ha superado la puntuación máxima
|
||||
bool paused_ = false; // Indica si el juego está pausado (no se deberia de poder utilizar en el modo arcade)
|
||||
// bool paused_by_service_menu_ = false;
|
||||
float difficulty_score_multiplier_; // Multiplicador de puntos en función de la dificultad
|
||||
int counter_ = 0; // Contador para el juego
|
||||
int game_completed_counter_ = 0; // Contador para el tramo final, cuando se ha completado la partida y ya no aparecen más globos
|
||||
@@ -158,7 +159,6 @@ class Game {
|
||||
void checkEvents(); // Procesa los eventos del sistema en cola
|
||||
void checkState(); // Verifica y actualiza el estado actual del juego
|
||||
void setState(State state); // Cambia el estado del juego
|
||||
void pause(bool value); // Pausa o reanuda el juego
|
||||
void cleanVectors(); // Limpia vectores de elementos deshabilitados
|
||||
|
||||
// --- Gestión de estados del juego ---
|
||||
@@ -294,6 +294,7 @@ class Game {
|
||||
|
||||
void sendPlayerToTheBack(const std::shared_ptr<Player> &player); // Mueve el jugador para pintarlo al fondo de la lista de jugadores
|
||||
void sendPlayerToTheFront(const std::shared_ptr<Player> &player); // Mueve el jugador para pintarlo el primero de la lista de jugadores
|
||||
void onPauseStateChanged(bool isPaused);
|
||||
|
||||
// SISTEMA DE GRABACIÓN (CONDICIONAL)
|
||||
#ifdef RECORDING
|
||||
|
||||
Reference in New Issue
Block a user