diff --git a/data/sound/continue_clock.wav b/data/sound/continue_clock.wav new file mode 100644 index 0000000..6542f67 Binary files /dev/null and b/data/sound/continue_clock.wav differ diff --git a/data/sound/walk.wav b/data/sound/walk.wav new file mode 100644 index 0000000..2a386ce Binary files /dev/null and b/data/sound/walk.wav differ diff --git a/source/director.cpp b/source/director.cpp index 7e85192..dbb2fb0 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -388,29 +388,31 @@ void Director::setFileList() Asset::get()->add(prefix + "/data/music/credits.ogg", AssetType::MUSIC); // Sonidos - Asset::get()->add(prefix + "/data/sound/game_start.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/balloon.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/bubble1.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/bubble2.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/bubble3.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/bubble4.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/bullet.wav", AssetType::SOUND); + Asset::get()->add(prefix + "/data/sound/clock.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/coffeeout.wav", AssetType::SOUND); + Asset::get()->add(prefix + "/data/sound/continue_clock.wav", AssetType::SOUND); + Asset::get()->add(prefix + "/data/sound/game_start.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/hiscore.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/itemdrop.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/itempickup.wav", AssetType::SOUND); - Asset::get()->add(prefix + "/data/sound/player_collision.wav", AssetType::SOUND); - Asset::get()->add(prefix + "/data/sound/stage_change.wav", AssetType::SOUND); - Asset::get()->add(prefix + "/data/sound/title.wav", AssetType::SOUND); - Asset::get()->add(prefix + "/data/sound/clock.wav", AssetType::SOUND); - Asset::get()->add(prefix + "/data/sound/powerball.wav", AssetType::SOUND); - Asset::get()->add(prefix + "/data/sound/notify.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/logo.wav", AssetType::SOUND); - Asset::get()->add(prefix + "/data/sound/voice_coffee.wav", AssetType::SOUND); - Asset::get()->add(prefix + "/data/sound/voice_power_up.wav", AssetType::SOUND); - Asset::get()->add(prefix + "/data/sound/voice_no.wav", AssetType::SOUND); - Asset::get()->add(prefix + "/data/sound/voice_get_ready.wav", AssetType::SOUND); + Asset::get()->add(prefix + "/data/sound/notify.wav", AssetType::SOUND); + Asset::get()->add(prefix + "/data/sound/player_collision.wav", AssetType::SOUND); + Asset::get()->add(prefix + "/data/sound/powerball.wav", AssetType::SOUND); + Asset::get()->add(prefix + "/data/sound/stage_change.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/tabe.wav", AssetType::SOUND); + Asset::get()->add(prefix + "/data/sound/title.wav", AssetType::SOUND); + Asset::get()->add(prefix + "/data/sound/voice_coffee.wav", AssetType::SOUND); + Asset::get()->add(prefix + "/data/sound/voice_get_ready.wav", AssetType::SOUND); + Asset::get()->add(prefix + "/data/sound/voice_no.wav", AssetType::SOUND); + Asset::get()->add(prefix + "/data/sound/voice_power_up.wav", AssetType::SOUND); + Asset::get()->add(prefix + "/data/sound/walk.wav", AssetType::SOUND); // Shaders Asset::get()->add(prefix + "/data/shaders/crtpi_256.glsl", AssetType::DATA); diff --git a/source/game.cpp b/source/game.cpp index 6b56fd0..7ca0e82 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -285,27 +285,6 @@ void Game::updateStage() } } -// Actualiza el estado de fade in -void Game::updateFadeInState() -{ - if (state_ == GameState::FADE_IN) - { - if (fade_in_->hasEnded()) - { - state_ = GameState::PLAYING; - - // Crea los primeros globos y el mensaje de inicio - if (!demo_.enabled) - { - balloon_manager_->createTwoBigBalloons(); - evaluateAndSetMenace(); - createMessage({paths_.at(0), paths_.at(1)}, Resource::get()->getTexture("game_text_get_ready")); - JA_PlaySound(Resource::get()->getSound("voice_get_ready.wav")); - } - } - } -} - // Actualiza el estado de fin de la partida void Game::updateGameOverState() { @@ -345,7 +324,7 @@ void Game::updateGameOverState() } // Gestiona eventos para el estado del final del juego -void Game::updateCompletedState() +void Game::updateGameStateCompleted() { if (state_ == GameState::COMPLETED) { @@ -583,11 +562,15 @@ void Game::checkBulletBalloonCollision() } // Mueve las balas activas -void Game::moveBullets() +void Game::updateBullets() { for (auto &bullet : bullets_) + { if (bullet->move() == BulletMoveStatus::OUT) + { getPlayer(bullet->getOwner())->decScoreMultiplier(); + } + } } // Pinta las balas activas @@ -802,28 +785,36 @@ void Game::throwCoffee(int x, int y) void Game::updateSmartSprites() { for (auto &sprite : smart_sprites_) + { sprite->update(); + } } // Pinta los SmartSprites activos void Game::renderSmartSprites() { for (auto &sprite : smart_sprites_) + { sprite->render(); + } } // Actualiza los PathSprites void Game::updatePathSprites() { for (auto &sprite : path_sprites_) + { sprite->update(); + } } // Pinta los PathSprites activos void Game::renderPathSprites() { for (auto &sprite : path_sprites_) + { sprite->render(); + } } // Acciones a realizar cuando el jugador muere @@ -895,7 +886,27 @@ void Game::update() #ifdef RECORDING updateRecording(); #endif - updateGame(); + // AQUI HAY QUE PONER UN SWITCH Y HACER EL UPDATE EN FUNCIÓN DEL ESTADO + switch (state_) + { + case GameState::PLAYING: + case GameState::COMPLETED: + case GameState::GAME_OVER: + updateGameStatePlaying(); + break; + case GameState::FADE_IN: + updateGameStateFadeIn(); + break; + case GameState::ENTERING_PLAYER: + updateGameStateEnteringPlayer(); + break; + case GameState::SHOWING_GET_READY_MESSAGE: + updateGameStateShowingGetReadyMessage(); + break; + + default: + break; + } checkMusicStatus(); screen_->update(); @@ -991,7 +1002,8 @@ void Game::disableTimeStopItem() void Game::checkMusicStatus() { // Si se ha completado el juego o los jugadores han terminado, detiene la música - if (state_ != GameState::COMPLETED && !allPlayersAreGameOver()) + // if (state_ != GameState::COMPLETED && !allPlayersAreGameOver()) + if (state_ == GameState::PLAYING) { playMusic(); } @@ -1194,7 +1206,7 @@ void Game::checkEvents() } case SDLK_6: // Crea un mensaje { - createMessage({paths_.at(2), paths_.at(3)}, Resource::get()->getTexture("game_text_congratulations")); + createMessage({paths_.at(0), paths_.at(1)}, Resource::get()->getTexture("game_text_get_ready")); break; } case SDLK_7: // Flash @@ -1705,7 +1717,7 @@ void Game::initPlayers(int player_id) // Activa el jugador que coincide con el "player_id" auto player = getPlayer(player_id); - player->setPlayingState(PlayerState::PLAYING); + player->setPlayingState(PlayerState::ENTERING_SCREEN); player->setInvulnerable(false); } @@ -1791,43 +1803,86 @@ void Game::updateRecording() } #endif -// Actualiza las variables durante el transcurso normal del juego -void Game::updateGame() +// Actualiza variables durande dicho estado +void Game::updateGameStateFadeIn() { - if (!paused_) + fade_in_->update(); + updateScoreboard(); + updateBackground(); + if (fade_in_->hasEnded()) { -#ifdef DEBUG - if (auto_pop_balloons_ && state_ == GameState::PLAYING) - { - Stage::addPower(5); - } -#endif - fade_in_->update(); - fade_out_->update(); - updatePlayers(); - checkPlayersStatusPlaying(); - updateScoreboard(); - updateBackground(); - balloon_manager_->update(); - tabe_->update(); - moveBullets(); - updateItems(); - updateStage(); - updateFadeInState(); - updateGameOverState(); - updateCompletedState(); - updateSmartSprites(); - updatePathSprites(); - updateTimeStopped(); - updateHelper(); - checkBulletBalloonCollision(); - updateMenace(); - checkAndUpdateBalloonSpeed(); - checkState(); - cleanVectors(); + state_ = GameState::ENTERING_PLAYER; + balloon_manager_->createTwoBigBalloons(); + evaluateAndSetMenace(); } } +// Actualiza variables durande dicho estado +void Game::updateGameStateEnteringPlayer() +{ + balloon_manager_->update(); + updatePlayers(); + updateScoreboard(); + updateBackground(); + for (auto player : players_) + { + if (player->isPlaying()) + { + state_ = GameState::SHOWING_GET_READY_MESSAGE; + createMessage({paths_.at(0), paths_.at(1)}, Resource::get()->getTexture("game_text_get_ready")); + JA_PlaySound(Resource::get()->getSound("voice_get_ready.wav")); + } + } +} + +// Actualiza variables durande dicho estado +void Game::updateGameStateShowingGetReadyMessage() +{ + balloon_manager_->update(); + updatePathSprites(); + updatePlayers(); + updateBullets(); + updateScoreboard(); + updateBackground(); + freePathSprites(); + if (path_sprites_.size() == 0) + { + state_ = GameState::PLAYING; + } +} + +// Actualiza las variables durante el transcurso normal del juego +void Game::updateGameStatePlaying() +{ +#ifdef DEBUG + if (auto_pop_balloons_ && state_ == GameState::PLAYING) + { + Stage::addPower(5); + } +#endif + fade_out_->update(); + updatePlayers(); + checkPlayersStatusPlaying(); + updateScoreboard(); + updateBackground(); + balloon_manager_->update(); + tabe_->update(); + updateBullets(); + updateItems(); + updateStage(); + updateGameOverState(); + updateGameStateCompleted(); + updateSmartSprites(); + updatePathSprites(); + updateTimeStopped(); + updateHelper(); + checkBulletBalloonCollision(); + updateMenace(); + checkAndUpdateBalloonSpeed(); + checkState(); + cleanVectors(); +} + // Vacía los vectores de elementos deshabilitados void Game::cleanVectors() { diff --git a/source/game.h b/source/game.h index 9237789..789c98f 100644 --- a/source/game.h +++ b/source/game.h @@ -67,6 +67,8 @@ private: enum class GameState { FADE_IN, + ENTERING_PLAYER, + SHOWING_GET_READY_MESSAGE, PLAYING, COMPLETED, GAME_OVER, @@ -197,9 +199,6 @@ private: // Comprueba si hay cambio de fase y actualiza las variables void updateStage(); - // Actualiza el estado de fade in - void updateFadeInState(); - // Actualiza el estado de fin de la partida void updateGameOverState(); @@ -216,7 +215,7 @@ private: void checkBulletBalloonCollision(); // Mueve las balas activas - void moveBullets(); + void updateBullets(); // Pinta las balas activas void renderBullets(); @@ -392,11 +391,20 @@ private: // Actualiza las variables durante el modo de grabación void updateRecording(); #endif + // Actualiza variables durande dicho estado + void updateGameStateFadeIn(); + + // Actualiza variables durande dicho estado + void updateGameStateEnteringPlayer(); + + // Actualiza variables durande dicho estado + void updateGameStateShowingGetReadyMessage(); + // Actualiza las variables durante el transcurso normal del juego - void updateGame(); + void updateGameStatePlaying(); // Gestiona eventos para el estado del final del juego - void updateCompletedState(); + void updateGameStateCompleted(); // Comprueba el estado del juego void checkState(); diff --git a/source/path_sprite.cpp b/source/path_sprite.cpp index 1f3dd72..1d158d6 100644 --- a/source/path_sprite.cpp +++ b/source/path_sprite.cpp @@ -95,7 +95,17 @@ void PathSprite::addPath(std::vector spots, int waiting_counter) // Habilita el objeto void PathSprite::enable() { + if (paths_.size() == 0) + { + return; + } + enabled_ = true; + + // Establece la posición + auto &path = paths_.at(current_path_); + const auto &p = path.spots.at(path.counter); + setPosition(p); } // Coloca el sprite en los diferentes puntos del recorrido diff --git a/source/player.cpp b/source/player.cpp index 05cb952..4c7e8e2 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -40,7 +40,7 @@ void Player::init() pos_y_ = default_pos_y_; walking_state_ = PlayerState::WALKING_STOP; firing_state_ = PlayerState::FIRING_NONE; - playing_state_ = PlayerState::WAITING; + setPlayingState(PlayerState::WAITING); invulnerable_ = true; invulnerable_counter_ = INVULNERABLE_COUNTER_; power_up_ = false; @@ -206,6 +206,12 @@ void Player::move() } case PlayerState::LEAVING_SCREEN: { + ++step_counter_; + if (step_counter_ % 10 == 0) + { + JA_PlaySound(Resource::get()->getSound("walk.wav")); + } + switch (id_) { case 1: @@ -224,7 +230,45 @@ void Player::move() shiftSprite(); if (pos_x_ == min_x || pos_x_ == max_x) + { setPlayingState(PlayerState::GAME_OVER); + } + break; + } + case PlayerState::ENTERING_SCREEN: + { + ++step_counter_; + if (step_counter_ % 10 == 0) + { + JA_PlaySound(Resource::get()->getSound("walk.wav")); + } + + switch (id_) + { + case 1: + setInputPlaying(InputType::RIGHT); + pos_x_ += vel_x_; + if (pos_x_ > default_pos_x_) + { + pos_x_ = default_pos_x_; + setPlayingState(PlayerState::PLAYING); + setInvulnerable(false); + } + break; + case 2: + setInputPlaying(InputType::LEFT); + pos_x_ += vel_x_; + if (pos_x_ < default_pos_x_) + { + pos_x_ = default_pos_x_; + setPlayingState(PlayerState::PLAYING); + setInvulnerable(false); + } + break; + default: + break; + } + shiftSprite(); break; } case PlayerState::CREDITS: @@ -291,6 +335,7 @@ void Player::setAnimation() { case PlayerState::PLAYING: case PlayerState::ENTERING_NAME_GAME_COMPLETED: + case PlayerState::ENTERING_SCREEN: case PlayerState::LEAVING_SCREEN: case PlayerState::CREDITS: { @@ -506,9 +551,29 @@ void Player::setPlayingState(PlayerState state) } case PlayerState::LEAVING_SCREEN: { + step_counter_ = 0; setScoreboardMode(ScoreboardMode::GAME_COMPLETED); break; } + case PlayerState::ENTERING_SCREEN: + { + step_counter_ = 0; + setScoreboardMode(ScoreboardMode::SCORE); + switch (id_) + { + case 1: + pos_x_ = param.game.game_area.rect.x - WIDTH_; + break; + + case 2: + pos_x_ = param.game.game_area.rect.x + param.game.game_area.rect.w; + break; + + default: + break; + } + break; + } case PlayerState::CREDITS: { vel_x_ = (walking_state_ == PlayerState::WALKING_RIGHT) ? BASE_SPEED_ : -BASE_SPEED_; @@ -648,6 +713,10 @@ void Player::decContinueCounter() { setPlayingState(PlayerState::GAME_OVER); } + else + { + JA_PlaySound(Resource::get()->getSound("continue_clock.wav")); + } } // Decrementa el contador de entrar nombre diff --git a/source/player.h b/source/player.h index ee7a409..66443c6 100644 --- a/source/player.h +++ b/source/player.h @@ -40,6 +40,7 @@ enum class PlayerState CELEBRATING, // Poniendo pose de victoria ENTERING_NAME_GAME_COMPLETED, // Poniendo nombre en el tramo final del juego LEAVING_SCREEN, // Moviendose fuera de la pantalla + ENTERING_SCREEN, // Entando a la pantalla CREDITS, // Estado para los creditos del juego }; @@ -91,6 +92,7 @@ private: bool demo_; // Para que el jugador sepa si está en el modo demostración int enter_name_counter_; // Contador para poner nombre Uint32 enter_name_ticks_ = 0; // Variable para poder cambiar el contador de poner nombre en función del tiempo + int step_counter_ = 0; // Cuenta los pasos para los estados en los que camina automáticamente // Actualiza el circulo de colisión a la posición del jugador void shiftColliders();