Compare commits
7 Commits
54292c9f8f
...
35f4bf690c
| Author | SHA1 | Date | |
|---|---|---|---|
| 35f4bf690c | |||
| abeaf47f96 | |||
| 6498c35628 | |||
| d1c6af02db | |||
| 5edef17d84 | |||
| e4532fcef2 | |||
| 7a8d66c29d |
61
TODO.md
Normal file
61
TODO.md
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# TODO
|
||||||
|
|
||||||
|
## Tareas pendientes
|
||||||
|
|
||||||
|
- [ ] Revisar todas las variables static de los métodos para ver si se resetean correctamente
|
||||||
|
|
||||||
|
## Mejoras arquitecturales (refactoring)
|
||||||
|
|
||||||
|
### Eliminar variables static locales y usar patrones profesionales:
|
||||||
|
|
||||||
|
**Opción 1: Máquina de Estados**
|
||||||
|
```cpp
|
||||||
|
class GameCompletedState {
|
||||||
|
bool start_celebrations_done = false;
|
||||||
|
bool end_celebrations_done = false;
|
||||||
|
float timer = 0.0f;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void reset() {
|
||||||
|
start_celebrations_done = false;
|
||||||
|
end_celebrations_done = false;
|
||||||
|
timer = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(float deltaTime) {
|
||||||
|
timer += deltaTime;
|
||||||
|
// lógica aquí
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**Opción 2: Sistema de Eventos/Callbacks**
|
||||||
|
```cpp
|
||||||
|
// Al entrar en COMPLETED state
|
||||||
|
eventSystem.scheduleEvent(6.0f, []{ startCelebrations(); });
|
||||||
|
eventSystem.scheduleEvent(14.0f, []{ endCelebrations(); });
|
||||||
|
```
|
||||||
|
|
||||||
|
**Opción 3: Flags como miembros privados**
|
||||||
|
```cpp
|
||||||
|
class Game {
|
||||||
|
private:
|
||||||
|
struct GameOverState {
|
||||||
|
bool game_over_triggered = false;
|
||||||
|
bool start_celebrations_triggered = false;
|
||||||
|
bool end_celebrations_triggered = false;
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
game_over_triggered = false;
|
||||||
|
start_celebrations_triggered = false;
|
||||||
|
end_celebrations_triggered = false;
|
||||||
|
}
|
||||||
|
} game_over_state_;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**Ventajas:**
|
||||||
|
- Más fáciles de testear
|
||||||
|
- Más fáciles de debugear
|
||||||
|
- Más fáciles de entender y mantener
|
||||||
|
- No tienen "estado oculto"
|
||||||
@@ -22,6 +22,7 @@ DEMODATA|${PREFIX}/data/demo/demo1.bin
|
|||||||
DEMODATA|${PREFIX}/data/demo/demo2.bin
|
DEMODATA|${PREFIX}/data/demo/demo2.bin
|
||||||
|
|
||||||
# Música
|
# Música
|
||||||
|
MUSIC|${PREFIX}/data/music/congratulations.ogg
|
||||||
MUSIC|${PREFIX}/data/music/credits.ogg
|
MUSIC|${PREFIX}/data/music/credits.ogg
|
||||||
MUSIC|${PREFIX}/data/music/intro.ogg
|
MUSIC|${PREFIX}/data/music/intro.ogg
|
||||||
MUSIC|${PREFIX}/data/music/playing.ogg
|
MUSIC|${PREFIX}/data/music/playing.ogg
|
||||||
@@ -48,6 +49,7 @@ SOUND|${PREFIX}/data/sound/item_drop.wav
|
|||||||
SOUND|${PREFIX}/data/sound/item_pickup.wav
|
SOUND|${PREFIX}/data/sound/item_pickup.wav
|
||||||
SOUND|${PREFIX}/data/sound/jump.wav
|
SOUND|${PREFIX}/data/sound/jump.wav
|
||||||
SOUND|${PREFIX}/data/sound/logo.wav
|
SOUND|${PREFIX}/data/sound/logo.wav
|
||||||
|
SOUND|${PREFIX}/data/sound/name_input_accept.wav
|
||||||
SOUND|${PREFIX}/data/sound/notify.wav
|
SOUND|${PREFIX}/data/sound/notify.wav
|
||||||
SOUND|${PREFIX}/data/sound/player_collision.wav
|
SOUND|${PREFIX}/data/sound/player_collision.wav
|
||||||
SOUND|${PREFIX}/data/sound/power_ball_explosion.wav
|
SOUND|${PREFIX}/data/sound/power_ball_explosion.wav
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ frames=38,39,40,41
|
|||||||
[animation]
|
[animation]
|
||||||
name=celebration
|
name=celebration
|
||||||
speed=0.167
|
speed=0.167
|
||||||
loop=-1
|
loop=0
|
||||||
frames=42,42,42,42,42,42,43,44,45,46,46,46,46,46,46,45,45,45,46,46,46,45,45,45,44,43,42,42,42
|
frames=42,42,42,42,42,42,43,44,45,46,46,46,46,46,46,45,45,45,46,46,46,45,45,45,44,43,42,42,42
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
"[GAME_TEXT] 7": "Endavant!",
|
"[GAME_TEXT] 7": "Endavant!",
|
||||||
"[GAME_TEXT] 8": "1.000.000 de punts!",
|
"[GAME_TEXT] 8": "1.000.000 de punts!",
|
||||||
"[GAME_TEXT] THANK_YOU": "Gracies!",
|
"[GAME_TEXT] THANK_YOU": "Gracies!",
|
||||||
|
"[GAME_TEXT] NEW_RECORD": "Nou record!",
|
||||||
|
|
||||||
"[HIGHSCORE_TABLE] CAPTION": "Millors puntuacions",
|
"[HIGHSCORE_TABLE] CAPTION": "Millors puntuacions",
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"[GAME_TEXT] 7": "Get Ready!",
|
"[GAME_TEXT] 7": "Get Ready!",
|
||||||
"[GAME_TEXT] 8": "1,000,000 points!",
|
"[GAME_TEXT] 8": "1,000,000 points!",
|
||||||
"[GAME_TEXT] THANK_YOU": "Thank you!",
|
"[GAME_TEXT] THANK_YOU": "Thank you!",
|
||||||
|
"[GAME_TEXT] NEW_RECORD": "New record!",
|
||||||
|
|
||||||
"[HIGHSCORE_TABLE] CAPTION": "Best scores",
|
"[HIGHSCORE_TABLE] CAPTION": "Best scores",
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"[GAME_TEXT] 7": "Adelante!",
|
"[GAME_TEXT] 7": "Adelante!",
|
||||||
"[GAME_TEXT] 8": "1.000.000 de puntos!",
|
"[GAME_TEXT] 8": "1.000.000 de puntos!",
|
||||||
"[GAME_TEXT] THANK_YOU": "Gracias!",
|
"[GAME_TEXT] THANK_YOU": "Gracias!",
|
||||||
|
"[GAME_TEXT] NEW_RECORD": "Nuevo record!",
|
||||||
|
|
||||||
"[HIGHSCORE_TABLE] CAPTION": "Mejores puntuaciones",
|
"[HIGHSCORE_TABLE] CAPTION": "Mejores puntuaciones",
|
||||||
|
|
||||||
|
|||||||
BIN
data/music/congratulations.ogg
Normal file
BIN
data/music/congratulations.ogg
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
data/sound/name_input_accept.wav
Normal file
BIN
data/sound/name_input_accept.wav
Normal file
Binary file not shown.
@@ -100,13 +100,33 @@ void Audio::stopAllSounds() const {
|
|||||||
|
|
||||||
// Realiza un fundido de salida de la música
|
// Realiza un fundido de salida de la música
|
||||||
void Audio::fadeOutMusic(int milliseconds) const {
|
void Audio::fadeOutMusic(int milliseconds) const {
|
||||||
if (music_enabled_ && music_.state == MusicState::PLAYING) {
|
if (music_enabled_ && getRealMusicState() == MusicState::PLAYING) {
|
||||||
#ifndef NO_AUDIO
|
#ifndef NO_AUDIO
|
||||||
JA_FadeOutMusic(milliseconds);
|
JA_FadeOutMusic(milliseconds);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Consulta directamente el estado real de la música en jailaudio
|
||||||
|
auto Audio::getRealMusicState() const -> MusicState {
|
||||||
|
#ifndef NO_AUDIO
|
||||||
|
JA_Music_state ja_state = JA_GetMusicState();
|
||||||
|
switch (ja_state) {
|
||||||
|
case JA_MUSIC_PLAYING:
|
||||||
|
return MusicState::PLAYING;
|
||||||
|
case JA_MUSIC_PAUSED:
|
||||||
|
return MusicState::PAUSED;
|
||||||
|
case JA_MUSIC_STOPPED:
|
||||||
|
case JA_MUSIC_INVALID:
|
||||||
|
case JA_MUSIC_DISABLED:
|
||||||
|
default:
|
||||||
|
return MusicState::STOPPED;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return MusicState::STOPPED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Establece el volumen de los sonidos
|
// Establece el volumen de los sonidos
|
||||||
void Audio::setSoundVolume(int sound_volume, Group group) const {
|
void Audio::setSoundVolume(int sound_volume, Group group) const {
|
||||||
if (sound_enabled_) {
|
if (sound_enabled_) {
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ class Audio {
|
|||||||
INTERFACE = 1 // Sonidos de la interfaz
|
INTERFACE = 1 // Sonidos de la interfaz
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class MusicState {
|
||||||
|
PLAYING, // Reproduciendo música
|
||||||
|
PAUSED, // Música pausada
|
||||||
|
STOPPED, // Música detenida
|
||||||
|
};
|
||||||
|
|
||||||
// --- Constantes ---
|
// --- Constantes ---
|
||||||
static constexpr int MAX_VOLUME = 100; // Volumen máximo
|
static constexpr int MAX_VOLUME = 100; // Volumen máximo
|
||||||
static constexpr int MIN_VOLUME = 0; // Volumen mínimo
|
static constexpr int MIN_VOLUME = 0; // Volumen mínimo
|
||||||
@@ -60,14 +66,15 @@ class Audio {
|
|||||||
void setSoundVolume(int volume, Group group = Group::ALL) const; // Ajustar volumen de efectos
|
void setSoundVolume(int volume, Group group = Group::ALL) const; // Ajustar volumen de efectos
|
||||||
void setMusicVolume(int volume) const; // Ajustar volumen de música
|
void setMusicVolume(int volume) const; // Ajustar volumen de música
|
||||||
|
|
||||||
private:
|
// --- Getters para debug ---
|
||||||
// --- Enums privados ---
|
bool isEnabled() const { return enabled_; }
|
||||||
enum class MusicState {
|
bool isSoundEnabled() const { return sound_enabled_; }
|
||||||
PLAYING, // Reproduciendo música
|
bool isMusicEnabled() const { return music_enabled_; }
|
||||||
PAUSED, // Música pausada
|
MusicState getMusicState() const { return music_.state; }
|
||||||
STOPPED, // Música detenida
|
MusicState getRealMusicState() const; // Consulta directamente a jailaudio
|
||||||
};
|
const std::string& getCurrentMusicName() const { return music_.name; }
|
||||||
|
|
||||||
|
private:
|
||||||
// --- Estructuras privadas ---
|
// --- Estructuras privadas ---
|
||||||
struct Music {
|
struct Music {
|
||||||
MusicState state; // Estado actual de la música (reproduciendo, detenido, en pausa)
|
MusicState state; // Estado actual de la música (reproduciendo, detenido, en pausa)
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ Director::Director(int argc, std::span<char *> argv) {
|
|||||||
Section::name = Section::Name::GAME;
|
Section::name = Section::Name::GAME;
|
||||||
Section::options = Section::Options::GAME_PLAY_1P;
|
Section::options = Section::Options::GAME_PLAY_1P;
|
||||||
#elif _DEBUG
|
#elif _DEBUG
|
||||||
Section::name = Section::Name::TITLE;
|
Section::name = Section::Name::GAME;
|
||||||
Section::options = Section::Options::GAME_PLAY_1P;
|
Section::options = Section::Options::GAME_PLAY_1P;
|
||||||
#else // NORMAL GAME
|
#else // NORMAL GAME
|
||||||
Section::name = Section::Name::LOGO;
|
Section::name = Section::Name::LOGO;
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ class Fade {
|
|||||||
void setColor(Color color); // Establece el color del fade
|
void setColor(Color color); // Establece el color del fade
|
||||||
void setType(Type type) { type_ = type; } // Establece el tipo de fade
|
void setType(Type type) { type_ = type; } // Establece el tipo de fade
|
||||||
void setMode(Mode mode) { mode_ = mode; } // Establece el modo de fade
|
void setMode(Mode mode) { mode_ = mode; } // Establece el modo de fade
|
||||||
void setPostDuration(int value) { post_duration_ = value; } // Duración posterior al fade en milisegundos
|
void setPostDuration(int milliseconds) { post_duration_ = milliseconds; } // Duración posterior al fade en milisegundos
|
||||||
void setPreDuration(int value) { pre_duration_ = value; } // Duración previa al fade en milisegundos
|
void setPreDuration(int milliseconds) { pre_duration_ = milliseconds; } // Duración previa al fade en milisegundos
|
||||||
|
|
||||||
// --- Getters ---
|
// --- Getters ---
|
||||||
[[nodiscard]] auto getValue() const -> int { return value_; }
|
[[nodiscard]] auto getValue() const -> int { return value_; }
|
||||||
|
|||||||
@@ -24,6 +24,32 @@ void ManageHiScoreTable::clear() {
|
|||||||
table_.emplace_back("PACMQ", 200);
|
table_.emplace_back("PACMQ", 200);
|
||||||
table_.emplace_back("PELEC", 100);
|
table_.emplace_back("PELEC", 100);
|
||||||
|
|
||||||
|
/*
|
||||||
|
table_.emplace_back("BRY", 1000);
|
||||||
|
table_.emplace_back("USUFO", 500);
|
||||||
|
table_.emplace_back("GLUCA", 100);
|
||||||
|
table_.emplace_back("PARRA", 50);
|
||||||
|
table_.emplace_back("CAGAM", 10);
|
||||||
|
table_.emplace_back("PEPE", 5);
|
||||||
|
table_.emplace_back("ROSIT", 4);
|
||||||
|
table_.emplace_back("SAM", 3);
|
||||||
|
table_.emplace_back("PACMQ", 2);
|
||||||
|
table_.emplace_back("PELEC", 1);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
table_.emplace_back("BRY", 5000000);
|
||||||
|
table_.emplace_back("USUFO", 5000000);
|
||||||
|
table_.emplace_back("GLUCA", 5000000);
|
||||||
|
table_.emplace_back("PARRA", 5000000);
|
||||||
|
table_.emplace_back("CAGAM", 5000000);
|
||||||
|
table_.emplace_back("PEPE", 5000000);
|
||||||
|
table_.emplace_back("ROSIT", 5000000);
|
||||||
|
table_.emplace_back("SAM", 5000000);
|
||||||
|
table_.emplace_back("PACMQ", 5000000);
|
||||||
|
table_.emplace_back("PELEC", 5000000);
|
||||||
|
*/
|
||||||
|
|
||||||
sort();
|
sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ void Player::setInputEnteringName(Input::Action action) {
|
|||||||
name_entry_idle_time_accumulator_ = 0.0f;
|
name_entry_idle_time_accumulator_ = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fase 1: Sistema de movimiento time-based
|
// Sistema de movimiento
|
||||||
void Player::move(float deltaTime) {
|
void Player::move(float deltaTime) {
|
||||||
switch (playing_state_) {
|
switch (playing_state_) {
|
||||||
case State::PLAYING:
|
case State::PLAYING:
|
||||||
@@ -475,11 +475,10 @@ auto Player::computeAnimation() const -> std::pair<std::string, SDL_FlipMode> {
|
|||||||
return {anim_name, flip_mode};
|
return {anim_name, flip_mode};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fase 1: Establece la animación correspondiente al estado (time-based)
|
// Establece la animación correspondiente al estado
|
||||||
void Player::setAnimation(float deltaTime) {
|
void Player::setAnimation(float deltaTime) {
|
||||||
switch (playing_state_) {
|
switch (playing_state_) {
|
||||||
case State::PLAYING:
|
case State::PLAYING:
|
||||||
case State::ENTERING_NAME_GAME_COMPLETED:
|
|
||||||
case State::ENTERING_SCREEN:
|
case State::ENTERING_SCREEN:
|
||||||
case State::LEAVING_SCREEN:
|
case State::LEAVING_SCREEN:
|
||||||
case State::TITLE_ANIMATION:
|
case State::TITLE_ANIMATION:
|
||||||
@@ -505,6 +504,7 @@ void Player::setAnimation(float deltaTime) {
|
|||||||
case State::CONTINUE:
|
case State::CONTINUE:
|
||||||
player_sprite_->setCurrentAnimation("dizzy");
|
player_sprite_->setCurrentAnimation("dizzy");
|
||||||
break;
|
break;
|
||||||
|
case State::ENTERING_NAME_GAME_COMPLETED:
|
||||||
case State::CELEBRATING:
|
case State::CELEBRATING:
|
||||||
player_sprite_->setCurrentAnimation("celebration");
|
player_sprite_->setCurrentAnimation("celebration");
|
||||||
break;
|
break;
|
||||||
@@ -679,8 +679,8 @@ void Player::setPlayingState(State state) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case State::ENTERING_NAME_GAME_COMPLETED: {
|
case State::ENTERING_NAME_GAME_COMPLETED: {
|
||||||
setWalkingState(State::WALKING_STOP);
|
// setWalkingState(State::WALKING_STOP);
|
||||||
setFiringState(State::FIRING_NONE);
|
// setFiringState(State::FIRING_NONE);
|
||||||
setScoreboardMode(Scoreboard::Mode::ENTER_NAME);
|
setScoreboardMode(Scoreboard::Mode::ENTER_NAME);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1034,19 +1034,35 @@ void Player::updateFiringStateFromVisual() {
|
|||||||
|
|
||||||
case VisualFireState::RECOILING:
|
case VisualFireState::RECOILING:
|
||||||
switch (base_state) {
|
switch (base_state) {
|
||||||
case State::FIRING_LEFT: firing_state_ = State::RECOILING_LEFT; break;
|
case State::FIRING_LEFT:
|
||||||
case State::FIRING_RIGHT: firing_state_ = State::RECOILING_RIGHT; break;
|
firing_state_ = State::RECOILING_LEFT;
|
||||||
case State::FIRING_UP: firing_state_ = State::RECOILING_UP; break;
|
break;
|
||||||
default: firing_state_ = State::RECOILING_UP; break;
|
case State::FIRING_RIGHT:
|
||||||
|
firing_state_ = State::RECOILING_RIGHT;
|
||||||
|
break;
|
||||||
|
case State::FIRING_UP:
|
||||||
|
firing_state_ = State::RECOILING_UP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
firing_state_ = State::RECOILING_UP;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VisualFireState::THREAT_POSE:
|
case VisualFireState::THREAT_POSE:
|
||||||
switch (base_state) {
|
switch (base_state) {
|
||||||
case State::FIRING_LEFT: firing_state_ = State::COOLING_LEFT; break;
|
case State::FIRING_LEFT:
|
||||||
case State::FIRING_RIGHT: firing_state_ = State::COOLING_RIGHT; break;
|
firing_state_ = State::COOLING_LEFT;
|
||||||
case State::FIRING_UP: firing_state_ = State::COOLING_UP; break;
|
break;
|
||||||
default: firing_state_ = State::COOLING_UP; break;
|
case State::FIRING_RIGHT:
|
||||||
|
firing_state_ = State::COOLING_RIGHT;
|
||||||
|
break;
|
||||||
|
case State::FIRING_UP:
|
||||||
|
firing_state_ = State::COOLING_UP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
firing_state_ = State::COOLING_UP;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -678,6 +678,7 @@ void Resource::createTextTextures() {
|
|||||||
{"game_text_get_ready", Lang::getText("[GAME_TEXT] 7")},
|
{"game_text_get_ready", Lang::getText("[GAME_TEXT] 7")},
|
||||||
{"game_text_last_stage", Lang::getText("[GAME_TEXT] 3")},
|
{"game_text_last_stage", Lang::getText("[GAME_TEXT] 3")},
|
||||||
{"game_text_congratulations", Lang::getText("[GAME_TEXT] 1")},
|
{"game_text_congratulations", Lang::getText("[GAME_TEXT] 1")},
|
||||||
|
{"game_text_new_record", Lang::getText("[GAME_TEXT] NEW_RECORD")},
|
||||||
{"game_text_game_over", "Game Over"}};
|
{"game_text_game_over", "Game Over"}};
|
||||||
|
|
||||||
auto text2 = getText("04b_25_2x_enhanced");
|
auto text2 = getText("04b_25_2x_enhanced");
|
||||||
|
|||||||
@@ -49,13 +49,13 @@ Credits::Credits()
|
|||||||
|
|
||||||
fade_in_->setColor(param.fade.color);
|
fade_in_->setColor(param.fade.color);
|
||||||
fade_in_->setType(Fade::Type::FULLSCREEN);
|
fade_in_->setType(Fade::Type::FULLSCREEN);
|
||||||
fade_in_->setPostDuration(static_cast<int>(50 * (1000.0f / 60.0f))); // 50 frames = ~833ms
|
fade_in_->setPostDuration(800);
|
||||||
fade_in_->setMode(Fade::Mode::IN);
|
fade_in_->setMode(Fade::Mode::IN);
|
||||||
fade_in_->activate();
|
fade_in_->activate();
|
||||||
|
|
||||||
fade_out_->setColor(0, 0, 0);
|
fade_out_->setColor(0, 0, 0);
|
||||||
fade_out_->setType(Fade::Type::FULLSCREEN);
|
fade_out_->setType(Fade::Type::FULLSCREEN);
|
||||||
fade_out_->setPostDuration(static_cast<int>(400 * (1000.0f / 60.0f))); // 400 frames = ~6667ms
|
fade_out_->setPostDuration(7000);
|
||||||
|
|
||||||
updateRedRect();
|
updateRedRect();
|
||||||
tiled_bg_->setColor(Color(255, 96, 96));
|
tiled_bg_->setColor(Color(255, 96, 96));
|
||||||
@@ -487,12 +487,12 @@ void Credits::updateAllFades(float deltaTime) {
|
|||||||
updateRedRect();
|
updateRedRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
fade_in_->update(); // Fade ya usa tiempo interno
|
fade_in_->update();
|
||||||
if (fade_in_->hasEnded()) {
|
if (fade_in_->hasEnded() && Audio::get()->getMusicState() != Audio::MusicState::PLAYING) {
|
||||||
Audio::get()->playMusic("credits.ogg");
|
Audio::get()->playMusic("credits.ogg");
|
||||||
}
|
}
|
||||||
|
|
||||||
fade_out_->update(); // Fade ya usa tiempo interno
|
fade_out_->update();
|
||||||
if (fade_out_->hasEnded()) {
|
if (fade_out_->hasEnded()) {
|
||||||
Section::name = Section::Name::HI_SCORE_TABLE;
|
Section::name = Section::Name::HI_SCORE_TABLE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,7 +117,14 @@ Game::~Game() {
|
|||||||
auto manager = std::make_unique<ManageHiScoreTable>(Options::settings.hi_score_table);
|
auto manager = std::make_unique<ManageHiScoreTable>(Options::settings.hi_score_table);
|
||||||
manager->saveToFile(Asset::get()->get("score.bin"));
|
manager->saveToFile(Asset::get()->get("score.bin"));
|
||||||
Section::attract_mode = Section::AttractMode::TITLE_TO_DEMO;
|
Section::attract_mode = Section::AttractMode::TITLE_TO_DEMO;
|
||||||
|
if (Options::audio.enabled) {
|
||||||
|
// Musica
|
||||||
Audio::get()->stopMusic();
|
Audio::get()->stopMusic();
|
||||||
|
Audio::get()->setMusicVolume(Options::audio.music.volume);
|
||||||
|
// Sonidos
|
||||||
|
Audio::get()->stopAllSounds();
|
||||||
|
Audio::get()->setSoundVolume(Options::audio.sound.volume, Audio::Group::GAME);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ServiceMenu::get()->setStateChangeCallback(nullptr);
|
ServiceMenu::get()->setStateChangeCallback(nullptr);
|
||||||
|
|
||||||
@@ -201,10 +208,11 @@ void Game::updateHiScore() {
|
|||||||
hi_score_.score = player->getScore();
|
hi_score_.score = player->getScore();
|
||||||
hi_score_.name.clear();
|
hi_score_.name.clear();
|
||||||
|
|
||||||
// Si se supera la máxima puntuación emite sonido
|
// Si se supera la máxima puntuación
|
||||||
if (!hi_score_achieved_) {
|
if (!hi_score_achieved_) {
|
||||||
hi_score_achieved_ = true;
|
hi_score_achieved_ = true;
|
||||||
playSound("hi_score_achieved.wav");
|
playSound("hi_score_achieved.wav"); // Emite un sonido
|
||||||
|
createMessage({paths_.at(8), paths_.at(9)}, Resource::get()->getTexture("game_text_new_record")); // CRea un mensaje
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -338,12 +346,11 @@ void Game::updateGameStateGameOver(float deltaTime) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fade_out_->isEnabled()) {
|
|
||||||
if (Options::audio.enabled) {
|
if (Options::audio.enabled) {
|
||||||
const float VOL = static_cast<float>(64 * (100 - fade_out_->getValue())) / 100.0F;
|
const float progress = std::min(game_over_timer_ / GAME_OVER_DURATION_S, 1.0f);
|
||||||
|
const float VOL = 64.0f * (1.0f - progress);
|
||||||
Audio::get()->setSoundVolume(static_cast<int>(VOL), Audio::Group::GAME);
|
Audio::get()->setSoundVolume(static_cast<int>(VOL), Audio::Group::GAME);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (fade_out_->hasEnded()) {
|
if (fade_out_->hasEnded()) {
|
||||||
if (game_completed_timer_ > 0) {
|
if (game_completed_timer_ > 0) {
|
||||||
@@ -352,10 +359,6 @@ void Game::updateGameStateGameOver(float deltaTime) {
|
|||||||
Section::name = Section::Name::HI_SCORE_TABLE; // La partida ha terminado con la derrota de los jugadores
|
Section::name = Section::Name::HI_SCORE_TABLE; // La partida ha terminado con la derrota de los jugadores
|
||||||
}
|
}
|
||||||
Section::options = Section::Options::HI_SCORE_AFTER_PLAYING;
|
Section::options = Section::Options::HI_SCORE_AFTER_PLAYING;
|
||||||
if (Options::audio.enabled) {
|
|
||||||
Audio::get()->stopAllSounds();
|
|
||||||
Audio::get()->setSoundVolume(Options::audio.sound.volume, Audio::Group::GAME);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1036,7 +1039,7 @@ void Game::initPaths() {
|
|||||||
const int X1 = param.game.play_area.center_x - (W / 2);
|
const int X1 = param.game.play_area.center_x - (W / 2);
|
||||||
const int X2 = param.game.play_area.rect.w;
|
const int X2 = param.game.play_area.rect.w;
|
||||||
const int Y = param.game.play_area.center_y;
|
const int Y = param.game.play_area.center_y;
|
||||||
paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 0.33f); // 20 frames → segundos
|
paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 0.5f);
|
||||||
paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0);
|
paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1048,11 +1051,11 @@ void Game::initPaths() {
|
|||||||
const int Y1 = param.game.play_area.center_y - (H / 2);
|
const int Y1 = param.game.play_area.center_y - (H / 2);
|
||||||
const int Y2 = -H;
|
const int Y2 = -H;
|
||||||
const int X = param.game.play_area.center_x;
|
const int X = param.game.play_area.center_x;
|
||||||
paths_.emplace_back(createPath(Y0, Y1, PathType::VERTICAL, X, 80, easeOutQuint), 0.33f); // 20 frames → segundos
|
paths_.emplace_back(createPath(Y0, Y1, PathType::VERTICAL, X, 80, easeOutQuint), 0.5f);
|
||||||
paths_.emplace_back(createPath(Y1, Y2, PathType::VERTICAL, X, 80, easeInQuint), 0);
|
paths_.emplace_back(createPath(Y1, Y2, PathType::VERTICAL, X, 80, easeInQuint), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recorrido para el texto de "Congratulations!!" (3,4)
|
// Recorrido para el texto de "Congratulations!!" (4,5)
|
||||||
{
|
{
|
||||||
const auto &texture = Resource::get()->getTexture("game_text_congratulations");
|
const auto &texture = Resource::get()->getTexture("game_text_congratulations");
|
||||||
const auto W = texture->getWidth();
|
const auto W = texture->getWidth();
|
||||||
@@ -1060,12 +1063,12 @@ void Game::initPaths() {
|
|||||||
const int X0 = -W;
|
const int X0 = -W;
|
||||||
const int X1 = param.game.play_area.center_x - (W / 2);
|
const int X1 = param.game.play_area.center_x - (W / 2);
|
||||||
const int X2 = param.game.play_area.rect.w;
|
const int X2 = param.game.play_area.rect.w;
|
||||||
const int Y = param.game.play_area.center_y - (H / 2) - 20;
|
const int Y = param.game.play_area.center_y - (H / 2);
|
||||||
paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 6.67f); // 400 frames → segundos
|
paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 7.0F);
|
||||||
paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0);
|
paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recorrido para el texto de "1.000.000 points!" (5,6)
|
// Recorrido para el texto de "1.000.000 points!" (6,7)
|
||||||
{
|
{
|
||||||
const auto &texture = Resource::get()->getTexture("game_text_1000000_points");
|
const auto &texture = Resource::get()->getTexture("game_text_1000000_points");
|
||||||
const auto W = texture->getWidth();
|
const auto W = texture->getWidth();
|
||||||
@@ -1073,8 +1076,21 @@ void Game::initPaths() {
|
|||||||
const int X0 = param.game.play_area.rect.w;
|
const int X0 = param.game.play_area.rect.w;
|
||||||
const int X1 = param.game.play_area.center_x - (W / 2);
|
const int X1 = param.game.play_area.center_x - (W / 2);
|
||||||
const int X2 = -W;
|
const int X2 = -W;
|
||||||
const int Y = param.game.play_area.center_y + (H / 2) - 20;
|
const int Y = param.game.play_area.center_y + (H / 2);
|
||||||
paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 6.67f); // 400 frames → segundos
|
paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 7.0F);
|
||||||
|
paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recorrido para el texto de "New Record!" (8,9)
|
||||||
|
{
|
||||||
|
const auto &texture = Resource::get()->getTexture("game_text_new_record");
|
||||||
|
const auto W = texture->getWidth();
|
||||||
|
const auto H = texture->getHeight();
|
||||||
|
const int X0 = -W;
|
||||||
|
const int X1 = param.game.play_area.center_x - (W / 2);
|
||||||
|
const int X2 = param.game.play_area.rect.w;
|
||||||
|
const int Y = param.game.play_area.center_y - (H / 2) - (H * 2);
|
||||||
|
paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 1.0f);
|
||||||
paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0);
|
paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1486,7 +1502,7 @@ void Game::handleNameInput(const std::shared_ptr<Player> &player) {
|
|||||||
}
|
}
|
||||||
player->setInput(Input::Action::START);
|
player->setInput(Input::Action::START);
|
||||||
player->setPlayingState(Player::State::SHOWING_NAME);
|
player->setPlayingState(Player::State::SHOWING_NAME);
|
||||||
playSound("service_menu_select.wav");
|
playSound("name_input_accept.wav");
|
||||||
updateHiScoreName();
|
updateHiScoreName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1645,8 +1661,8 @@ void Game::initPlayers(Player::Id player_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hace sonar la música
|
// Hace sonar la música
|
||||||
void Game::playMusic() {
|
void Game::playMusic(const std::string &music_file, int loop) {
|
||||||
Audio::get()->playMusic("playing.ogg");
|
Audio::get()->playMusic(music_file, loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pausa la música
|
// Pausa la música
|
||||||
@@ -1751,24 +1767,21 @@ void Game::updateGameStateEnteringPlayer(float deltaTime) {
|
|||||||
void Game::updateGameStateShowingGetReadyMessage(float deltaTime) {
|
void Game::updateGameStateShowingGetReadyMessage(float deltaTime) {
|
||||||
updateGameStatePlaying(deltaTime);
|
updateGameStatePlaying(deltaTime);
|
||||||
|
|
||||||
// Reproducir música después de ~1.67 segundos (100 frames a 60fps)
|
constexpr float MUSIC_START_S = 1.67F;
|
||||||
static bool music_started = false;
|
|
||||||
static float music_timer = 0.0f;
|
static float music_timer = 0.0f;
|
||||||
if (!music_started) {
|
|
||||||
music_timer += deltaTime;
|
music_timer += deltaTime;
|
||||||
if (music_timer >= 1.67f) {
|
if (music_timer >= MUSIC_START_S) {
|
||||||
playMusic();
|
playMusic("playing.ogg");
|
||||||
music_started = true;
|
music_timer = 0.0F;
|
||||||
setState(State::PLAYING);
|
setState(State::PLAYING);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza las variables durante el transcurso normal del juego
|
// Actualiza las variables durante el transcurso normal del juego
|
||||||
void Game::updateGameStatePlaying(float deltaTime) {
|
void Game::updateGameStatePlaying(float deltaTime) {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if (auto_pop_balloons_) {
|
if (auto_pop_balloons_) {
|
||||||
stage_manager_->addPower(1);
|
stage_manager_->addPower(2);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
updatePlayers(deltaTime);
|
updatePlayers(deltaTime);
|
||||||
@@ -1922,11 +1935,19 @@ void Game::onPauseStateChanged(bool is_paused) {
|
|||||||
|
|
||||||
// Maneja eventos del juego completado usando flags para triggers únicos
|
// Maneja eventos del juego completado usando flags para triggers únicos
|
||||||
void Game::handleGameCompletedEvents() {
|
void Game::handleGameCompletedEvents() {
|
||||||
constexpr float START_CELEBRATIONS_S = 6.667f; // 400 frames a 60fps → segundos
|
static bool start_celebrations_triggered = false;
|
||||||
constexpr float END_CELEBRATIONS_S = 11.667f; // 700 frames a 60fps → segundos
|
static bool end_celebrations_triggered = false;
|
||||||
|
|
||||||
|
// Resetear
|
||||||
|
if (game_completed_timer_ == 0.0f) {
|
||||||
|
start_celebrations_triggered = false;
|
||||||
|
end_celebrations_triggered = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr float START_CELEBRATIONS_S = 6.0f;
|
||||||
|
constexpr float END_CELEBRATIONS_S = 14.0f;
|
||||||
|
|
||||||
// Inicio de celebraciones
|
// Inicio de celebraciones
|
||||||
static bool start_celebrations_triggered = false;
|
|
||||||
if (!start_celebrations_triggered && game_completed_timer_ >= START_CELEBRATIONS_S) {
|
if (!start_celebrations_triggered && game_completed_timer_ >= START_CELEBRATIONS_S) {
|
||||||
createMessage({paths_.at(4), paths_.at(5)}, Resource::get()->getTexture("game_text_congratulations"));
|
createMessage({paths_.at(4), paths_.at(5)}, Resource::get()->getTexture("game_text_congratulations"));
|
||||||
createMessage({paths_.at(6), paths_.at(7)}, Resource::get()->getTexture("game_text_1000000_points"));
|
createMessage({paths_.at(6), paths_.at(7)}, Resource::get()->getTexture("game_text_1000000_points"));
|
||||||
@@ -1941,19 +1962,17 @@ void Game::handleGameCompletedEvents() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateHiScore();
|
updateHiScore();
|
||||||
|
playMusic("congratulations.ogg", 1);
|
||||||
start_celebrations_triggered = true;
|
start_celebrations_triggered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fin de celebraciones
|
// Fin de celebraciones
|
||||||
static bool end_celebrations_triggered = false;
|
|
||||||
if (!end_celebrations_triggered && game_completed_timer_ >= END_CELEBRATIONS_S) {
|
if (!end_celebrations_triggered && game_completed_timer_ >= END_CELEBRATIONS_S) {
|
||||||
for (auto &player : players_) {
|
for (auto &player : players_) {
|
||||||
if (player->isCelebrating()) {
|
if (player->isCelebrating()) {
|
||||||
player->setPlayingState(player->qualifiesForHighScore() ? Player::State::ENTERING_NAME_GAME_COMPLETED : Player::State::LEAVING_SCREEN);
|
player->setPlayingState(player->qualifiesForHighScore() ? Player::State::ENTERING_NAME_GAME_COMPLETED : Player::State::LEAVING_SCREEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fade_out_->activate();
|
|
||||||
end_celebrations_triggered = true;
|
end_celebrations_triggered = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1961,6 +1980,12 @@ void Game::handleGameCompletedEvents() {
|
|||||||
// Maneja eventos de game over usando flag para trigger único
|
// Maneja eventos de game over usando flag para trigger único
|
||||||
void Game::handleGameOverEvents() {
|
void Game::handleGameOverEvents() {
|
||||||
static bool game_over_triggered = false;
|
static bool game_over_triggered = false;
|
||||||
|
|
||||||
|
// Resetear
|
||||||
|
if (game_over_timer_ == 0.0f) {
|
||||||
|
game_over_triggered = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!game_over_triggered && game_over_timer_ == 0.0f) {
|
if (!game_over_triggered && game_over_timer_ == 0.0f) {
|
||||||
createMessage({paths_.at(2), paths_.at(3)}, Resource::get()->getTexture("game_text_game_over"));
|
createMessage({paths_.at(2), paths_.at(3)}, Resource::get()->getTexture("game_text_game_over"));
|
||||||
Audio::get()->fadeOutMusic(1000);
|
Audio::get()->fadeOutMusic(1000);
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ class Game {
|
|||||||
static constexpr float HELP_COUNTER_S = 16.667f; // Contador de ayuda (1000 frames a 60fps → segundos)
|
static constexpr float HELP_COUNTER_S = 16.667f; // Contador de ayuda (1000 frames a 60fps → segundos)
|
||||||
static constexpr float GAME_COMPLETED_START_FADE_S = 8.333f; // Inicio del fade al completar (500 frames → segundos)
|
static constexpr float GAME_COMPLETED_START_FADE_S = 8.333f; // Inicio del fade al completar (500 frames → segundos)
|
||||||
static constexpr float GAME_COMPLETED_END_S = 11.667f; // Fin del juego completado (700 frames → segundos)
|
static constexpr float GAME_COMPLETED_END_S = 11.667f; // Fin del juego completado (700 frames → segundos)
|
||||||
static constexpr float GAME_OVER_DURATION_S = 5.833f; // Duración game over (350 frames → segundos)
|
static constexpr float GAME_OVER_DURATION_S = 7.0f; // Duración game over (350 frames → segundos)
|
||||||
static constexpr float TIME_STOPPED_DURATION_S = 6.0f; // Duración del tiempo detenido (360 frames → segundos)
|
static constexpr float TIME_STOPPED_DURATION_S = 6.0f; // Duración del tiempo detenido (360 frames → segundos)
|
||||||
static constexpr float DEMO_FADE_PRE_DURATION_S = 0.5f; // Pre-duración del fade en modo demo
|
static constexpr float DEMO_FADE_PRE_DURATION_S = 0.5f; // Pre-duración del fade en modo demo
|
||||||
static constexpr int ITEM_POINTS_1_DISK_ODDS = 10;
|
static constexpr int ITEM_POINTS_1_DISK_ODDS = 10;
|
||||||
@@ -301,7 +301,7 @@ class Game {
|
|||||||
void updateHelper(); // Actualiza variables auxiliares de renderizado
|
void updateHelper(); // Actualiza variables auxiliares de renderizado
|
||||||
|
|
||||||
// --- Sistema de audio ---
|
// --- Sistema de audio ---
|
||||||
static void playMusic(); // Reproduce la música de fondo
|
static void playMusic(const std::string &music_file, int loop = -1); // Reproduce la música de fondo
|
||||||
void stopMusic() const; // Detiene la reproducción de música
|
void stopMusic() const; // Detiene la reproducción de música
|
||||||
static void pauseMusic(); // Pausa la música
|
static void pauseMusic(); // Pausa la música
|
||||||
static void resumeMusic(); // Retoma la música que eestaba pausada
|
static void resumeMusic(); // Retoma la música que eestaba pausada
|
||||||
|
|||||||
Reference in New Issue
Block a user