eliminats tots els SDL_Delay i bucles bloquejants (milestone 1)
- shakeScreen() convertit a màquina d'estats amb SDL_GetTicks (50ms per pas) - killPlayer() convertit a seqüència de fases (Shaking → Waiting → Done) - Fade FADE_FULLSCREEN convertit a per-frame amb alpha incremental - Fade FADE_RANDOM_SQUARE convertit a per-frame (un quadrat cada 100ms) - Title SUBSECTION_TITLE_2 convertit a no-bloquejant, variables static eliminades - Corregit so duplicat del crashSound al títol - Congelat input del jugador durant la seqüència de mort Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
117
source/game.cpp
117
source/game.cpp
@@ -284,6 +284,12 @@ void Game::init() {
|
||||
effect.flash = false;
|
||||
effect.shake = false;
|
||||
effect.shakeCounter = SHAKE_COUNTER;
|
||||
deathShake.active = false;
|
||||
deathShake.step = 0;
|
||||
deathShake.lastStepTicks = 0;
|
||||
deathSequence.phase = DeathPhase::None;
|
||||
deathSequence.phaseStartTicks = 0;
|
||||
deathSequence.player = nullptr;
|
||||
helper.needCoffee = false;
|
||||
helper.needCoffeeMachine = false;
|
||||
helper.needPowerBall = false;
|
||||
@@ -2363,23 +2369,50 @@ void Game::killPlayer(Player *player) {
|
||||
player->removeExtraHit();
|
||||
throwCoffee(player->getPosX() + (player->getWidth() / 2), player->getPosY() + (player->getHeight() / 2));
|
||||
JA_PlaySound(coffeeOutSound);
|
||||
} else {
|
||||
} else if (deathSequence.phase == DeathPhase::None) {
|
||||
JA_PauseMusic();
|
||||
stopAllBalloons(10);
|
||||
JA_PlaySound(playerCollisionSound);
|
||||
shakeScreen();
|
||||
SDL_Delay(500);
|
||||
JA_PlaySound(coffeeOutSound);
|
||||
player->setAlive(false);
|
||||
if (allPlayersAreDead()) {
|
||||
JA_StopMusic();
|
||||
} else {
|
||||
JA_ResumeMusic();
|
||||
}
|
||||
deathSequence.phase = DeathPhase::Shaking;
|
||||
deathSequence.phaseStartTicks = SDL_GetTicks();
|
||||
deathSequence.player = player;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza la secuencia de muerte del jugador
|
||||
void Game::updateDeathSequence() {
|
||||
switch (deathSequence.phase) {
|
||||
case DeathPhase::None:
|
||||
case DeathPhase::Done:
|
||||
break;
|
||||
|
||||
case DeathPhase::Shaking:
|
||||
// Espera a que termine el efecto de agitación
|
||||
if (!isDeathShaking()) {
|
||||
deathSequence.phase = DeathPhase::Waiting;
|
||||
deathSequence.phaseStartTicks = SDL_GetTicks();
|
||||
}
|
||||
break;
|
||||
|
||||
case DeathPhase::Waiting:
|
||||
// Espera 500ms antes de completar la muerte
|
||||
if (SDL_GetTicks() - deathSequence.phaseStartTicks >= 500) {
|
||||
JA_PlaySound(coffeeOutSound);
|
||||
deathSequence.player->setAlive(false);
|
||||
if (allPlayersAreDead()) {
|
||||
JA_StopMusic();
|
||||
} else {
|
||||
JA_ResumeMusic();
|
||||
}
|
||||
deathSequence.phase = DeathPhase::Done;
|
||||
deathSequence.player = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Calcula y establece el valor de amenaza en funcion de los globos activos
|
||||
void Game::evaluateAndSetMenace() {
|
||||
menaceCurrent = 0;
|
||||
@@ -2439,6 +2472,15 @@ void Game::update() {
|
||||
// Actualiza el audio
|
||||
JA_Update();
|
||||
|
||||
// Actualiza los efectos basados en tiempo real (no en el throttle del juego)
|
||||
updateDeathShake();
|
||||
updateDeathSequence();
|
||||
|
||||
// Durante la secuencia de muerte, congela el resto del juego
|
||||
if (deathSequence.phase == DeathPhase::Shaking || deathSequence.phase == DeathPhase::Waiting) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
|
||||
if (SDL_GetTicks() - ticks > ticksSpeed) {
|
||||
// Actualiza el contador de ticks
|
||||
@@ -2550,7 +2592,10 @@ void Game::updateBackground() {
|
||||
grassSprite->setSpriteClip(0, (6 * (counter / 20 % 2)), 256, 6);
|
||||
|
||||
// Mueve los edificios en funcion de si está activo el efecto de agitarlos
|
||||
if (effect.shake) {
|
||||
if (deathShake.active) {
|
||||
const int v[] = {-1, 1, -1, 1, -1, 1, -1, 0};
|
||||
buildingsSprite->setPosX(v[deathShake.step]);
|
||||
} else if (effect.shake) {
|
||||
buildingsSprite->setPosX(((effect.shakeCounter % 2) * 2) - 1);
|
||||
} else {
|
||||
buildingsSprite->setPosX(0);
|
||||
@@ -2868,44 +2913,32 @@ void Game::disableTimeStopItem() {
|
||||
}
|
||||
}
|
||||
|
||||
// Agita la pantalla
|
||||
// Inicia el efecto de agitación intensa de la pantalla
|
||||
void Game::shakeScreen() {
|
||||
const int v[] = {-1, 1, -1, 1, -1, 1, -1, 0};
|
||||
for (int n = 0; n < 8; ++n) {
|
||||
// Prepara para empezar a dibujar en la textura de juego
|
||||
screen->start();
|
||||
deathShake.active = true;
|
||||
deathShake.step = 0;
|
||||
deathShake.lastStepTicks = SDL_GetTicks();
|
||||
}
|
||||
|
||||
// Limpia la pantalla
|
||||
screen->clean(bgColor);
|
||||
// Actualiza el efecto de agitación intensa
|
||||
void Game::updateDeathShake() {
|
||||
if (!deathShake.active) return;
|
||||
|
||||
// Dibuja los objetos
|
||||
buildingsSprite->setPosX(0);
|
||||
buildingsSprite->setWidth(1);
|
||||
buildingsSprite->setSpriteClip(0, 0, 1, 160);
|
||||
renderBackground();
|
||||
|
||||
buildingsSprite->setPosX(255);
|
||||
buildingsSprite->setSpriteClip(255, 0, 1, 160);
|
||||
buildingsSprite->render();
|
||||
|
||||
buildingsSprite->setPosX(v[n]);
|
||||
buildingsSprite->setWidth(256);
|
||||
buildingsSprite->setSpriteClip(0, 0, 256, 160);
|
||||
buildingsSprite->render();
|
||||
|
||||
grassSprite->render();
|
||||
renderBalloons();
|
||||
renderBullets();
|
||||
renderItems();
|
||||
renderPlayers();
|
||||
renderScoreBoard();
|
||||
|
||||
// Vuelca el contenido del renderizador en pantalla
|
||||
screen->blit();
|
||||
SDL_Delay(50);
|
||||
Uint32 now = SDL_GetTicks();
|
||||
if (now - deathShake.lastStepTicks >= 50) {
|
||||
deathShake.lastStepTicks = now;
|
||||
deathShake.step++;
|
||||
if (deathShake.step >= 8) {
|
||||
deathShake.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Indica si el efecto de agitación intensa está activo
|
||||
bool Game::isDeathShaking() {
|
||||
return deathShake.active;
|
||||
}
|
||||
|
||||
// Bucle para el juego
|
||||
void Game::run() {
|
||||
while (section->name == SECTION_PROG_GAME) {
|
||||
|
||||
Reference in New Issue
Block a user