From 7ac46876ca2f75a3270781a43c6411eeec78c492 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Fri, 11 Jul 2025 22:03:44 +0200 Subject: [PATCH] Refet el spritesheet del jugador i el fitxer d'animacions Afegits nous estats per al jugador: RECOIL --- data/gfx/player/player.ani | 74 +++++++++++++++------- data/gfx/player/player1.gif | Bin 10709 -> 11999 bytes source/balloon_manager.h | 2 +- source/director.cpp | 2 +- source/player.cpp | 120 +++++++++++++++++++++++------------- source/player.h | 16 ++++- source/sections/game.cpp | 70 +++++++++++++++------ 7 files changed, 194 insertions(+), 90 deletions(-) diff --git a/data/gfx/player/player.ani b/data/gfx/player/player.ani index cea7556..c276435 100644 --- a/data/gfx/player/player.ani +++ b/data/gfx/player/player.ani @@ -16,78 +16,106 @@ frames=4,5,6,7 [/animation] [animation] -name=walk-sideshoot +name=walk-fire-side speed=5 loop=0 frames=8,9,10,11 [/animation] [animation] -name=walk-sideshoot-cooldown +name=walk-recoil-side speed=5 loop=0 frames=12,13,14,15 [/animation] [animation] -name=stand-sideshoot +name=walk-cool-side speed=5 loop=0 frames=16,17,18,19 [/animation] [animation] -name=stand-sideshoot-cooldown +name=stand-fire-side speed=5 loop=0 -frames=15 +frames=20 [/animation] [animation] -name=walk-centershoot +name=stand-recoil-side speed=5 loop=0 -frames=20,21,22,23 +frames=21 [/animation] [animation] -name=walk-centershoot-cooldown +name=stand-cool-side speed=5 loop=0 -frames=24,25,26,27 +frames=22 [/animation] [animation] -name=stand-centershoot +name=walk-fire-center speed=5 loop=0 -frames=28,29,30,31 +frames=23,24,25,26 [/animation] [animation] -name=stand-centershoot-cooldown +name=walk-recoil-center speed=5 loop=0 -frames=27 +frames=27,28,29,30 [/animation] [animation] -name=dying +name=walk-cool-center +speed=5 +loop=0 +frames=31,32,33,34 +[/animation] + +[animation] +name=stand-fire-center +speed=5 +loop=0 +frames=35 +[/animation] + +[animation] +name=stand-recoil-center +speed=5 +loop=0 +frames=36 +[/animation] + +[animation] +name=stand-cool-center +speed=5 +loop=0 +frames=37 +[/animation] + +[animation] +name=rolling speed=10 loop=0 -frames=32,33,34,35 -[/animation] - -[animation] -name=dead -speed=3 -loop=0 -frames=44,45,46,47,48,49,50 +frames=38,39,40,41 [/animation] [animation] name=celebration speed=10 loop=-1 -frames=36,36,36,36,36,36,37,38,39,40,40,40,40,40,40,39,39,39,40,40,40,39,39,39,38,37,36,36,36 +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] +name=dead +speed=5 +loop=0 +frames=47,48,49,50,51,52,53 [/animation] \ No newline at end of file diff --git a/data/gfx/player/player1.gif b/data/gfx/player/player1.gif index fe6044b95c46aeff4c0e8c8a70cc486aff509445..ce1f9e83c66a276d9a6882cf1df05ca88296581b 100644 GIT binary patch delta 10143 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 NNMZ+rE>0E#06UR|60iUO delta 8842 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 z9q(}(@An|-@gl=init(last_enter_name_); // Establece la posición del sprite @@ -358,41 +358,49 @@ void Player::setAnimation() case PlayerState::CREDITS: { // Crea cadenas de texto para componer el nombre de la animación - const std::string WALKING_ANIMATION = walking_state_ == PlayerState::WALKING_STOP ? "stand" : "walk"; - const std::string FIRING_ANIMATION = firing_state_ == PlayerState::FIRING_UP ? "centershoot" : "sideshoot"; - const std::string COOLING_ANIMATION = firing_state_ == PlayerState::COOLING_UP ? "centershoot" : "sideshoot"; + const std::string WALK_ANIMATION = walking_state_ == PlayerState::WALKING_STOP ? "stand" : "walk"; + const std::string FIRE_ANIMATION = firing_state_ == PlayerState::FIRING_UP ? "-fire-center" : "-fire-side"; + const std::string RECOIL_ANIMATION = firing_state_ == PlayerState::RECOILING_UP ? "-recoil-center" : "-recoil-side"; + const std::string COOL_ANIMATION = firing_state_ == PlayerState::COOLING_UP ? "-cool-center" : "-cool-side"; const SDL_FlipMode FLIP_WALK = walking_state_ == PlayerState::WALKING_RIGHT ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; const SDL_FlipMode FLIP_FIRE = firing_state_ == PlayerState::FIRING_RIGHT ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; - const SDL_FlipMode FLIP_COOLING = firing_state_ == PlayerState::COOLING_RIGHT ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; + const SDL_FlipMode FLIP_RECOIL = firing_state_ == PlayerState::RECOILING_RIGHT ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; + const SDL_FlipMode FLIP_COOL = firing_state_ == PlayerState::COOLING_RIGHT ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; // Establece la animación a partir de las cadenas if (firing_state_ == PlayerState::FIRING_NONE) { // No esta disparando - player_sprite_->setCurrentAnimation(WALKING_ANIMATION); + player_sprite_->setCurrentAnimation(WALK_ANIMATION); player_sprite_->setFlip(FLIP_WALK); } + else if (isRecoiling()) + { + // Retroceso + player_sprite_->setCurrentAnimation(WALK_ANIMATION + RECOIL_ANIMATION); + player_sprite_->setFlip(FLIP_RECOIL); + } else if (isCooling()) { // Acaba de disparar - player_sprite_->setCurrentAnimation(WALKING_ANIMATION + "-" + COOLING_ANIMATION + "-cooldown"); - player_sprite_->setFlip(FLIP_COOLING); + player_sprite_->setCurrentAnimation(WALK_ANIMATION + COOL_ANIMATION); + player_sprite_->setFlip(FLIP_COOL); } else { // Está disparando - player_sprite_->setCurrentAnimation(WALKING_ANIMATION + "-" + FIRING_ANIMATION); + player_sprite_->setCurrentAnimation(WALK_ANIMATION + FIRE_ANIMATION); // Si dispara de lado, invierte el sprite segun hacia donde dispara // Si dispara recto, invierte el sprite segun hacia donde camina - player_sprite_->setFlip(FIRING_ANIMATION == "centershoot" ? FLIP_WALK : FLIP_FIRE); + player_sprite_->setFlip(FIRE_ANIMATION == "-fire-center" ? FLIP_WALK : FLIP_FIRE); } break; } case PlayerState::DYING: case PlayerState::CONTINUE_TIME_OUT: { - player_sprite_->setCurrentAnimation("dying"); + player_sprite_->setCurrentAnimation("rolling"); break; } case PlayerState::LYING_ON_THE_FLOOR_FOREVER: @@ -419,38 +427,64 @@ void Player::setAnimation() // Actualiza el valor de la variable void Player::updateCooldown() { - if (cool_down_ > 0) + if (playing_state_ == PlayerState::PLAYING) { - --cool_down_; - cooling_state_counter_ = 50; - } - else - { - if (cooling_state_counter_ > 0) + if (cant_fire_counter_ > 0) { - if (cooling_state_counter_ == 40) + cooling_state_counter_ = COOLING_DURATION_; + + // La mitad del tiempo que no puede disparar tiene el brazo arriba (PlayerState::FIRING) + // y la otra mitad en retroceso (PlayerState::RECOILING) + if (cant_fire_counter_ == recoiling_state_duration_ / 2) { switch (firing_state_) { case PlayerState::FIRING_LEFT: - setFiringState(PlayerState::COOLING_LEFT); + setFiringState(PlayerState::RECOILING_LEFT); break; case PlayerState::FIRING_RIGHT: - setFiringState(PlayerState::COOLING_RIGHT); + setFiringState(PlayerState::RECOILING_RIGHT); break; case PlayerState::FIRING_UP: - setFiringState(PlayerState::COOLING_UP); + setFiringState(PlayerState::RECOILING_UP); break; default: break; } } - --cooling_state_counter_; + + --cant_fire_counter_; } else { - setFiringState(PlayerState::FIRING_NONE); - cooling_state_counter_ = 0; + if (cooling_state_counter_ > COOLING_COMPLETE_) + { + if (cooling_state_counter_ == COOLING_DURATION_) + { + switch (firing_state_) + { + case PlayerState::RECOILING_LEFT: + setFiringState(PlayerState::COOLING_LEFT); + break; + case PlayerState::RECOILING_RIGHT: + setFiringState(PlayerState::COOLING_RIGHT); + break; + case PlayerState::RECOILING_UP: + setFiringState(PlayerState::COOLING_UP); + break; + default: + break; + } + } + + --cooling_state_counter_; + } + + if (cooling_state_counter_ == COOLING_COMPLETE_) + { + setFiringState(PlayerState::FIRING_NONE); + cooling_state_counter_ = -1; + } } } } @@ -464,10 +498,10 @@ void Player::update() updateCooldown(); updatePowerUp(); updateInvulnerable(); + updateScoreboard(); updateContinueCounter(); updateEnterNameCounter(); updateShowingName(); - updateScoreboard(); } // Incrementa la puntuación del jugador @@ -650,19 +684,20 @@ void Player::setInvulnerable(bool value) // Monitoriza el estado void Player::updateInvulnerable() { - if (invulnerable_) - { - if (invulnerable_counter_ > 0) + if (playing_state_ == PlayerState::PLAYING) + if (invulnerable_) { - --invulnerable_counter_; - invulnerable_counter_ % 8 > 3 ? player_sprite_->getTexture()->setPalette(coffees_) : player_sprite_->getTexture()->setPalette(3); + if (invulnerable_counter_ > 0) + { + --invulnerable_counter_; + invulnerable_counter_ % 8 > 3 ? player_sprite_->getTexture()->setPalette(coffees_) : player_sprite_->getTexture()->setPalette(3); + } + else + { + setInvulnerable(false); + player_sprite_->getTexture()->setPalette(coffees_); + } } - else - { - setInvulnerable(false); - player_sprite_->getTexture()->setPalette(coffees_); - } - } } // Establece el valor de la variable @@ -675,11 +710,12 @@ void Player::setPowerUp() // Actualiza el valor de la variable void Player::updatePowerUp() { - if (power_up_) - { - --power_up_counter_; - power_up_ = power_up_counter_ > 0; - } + if (playing_state_ == PlayerState::PLAYING) + if (power_up_) + { + --power_up_counter_; + power_up_ = power_up_counter_ > 0; + } } // Concede un toque extra al jugador diff --git a/source/player.h b/source/player.h index f0761b1..9fed7b1 100644 --- a/source/player.h +++ b/source/player.h @@ -28,6 +28,11 @@ enum class PlayerState FIRING_RIGHT, // Disparando hacia la derecha FIRING_NONE, // No está disparando + // Estados de retroceso tras disparar + RECOILING_UP, // Retroceso tras disparar hacia arriba + RECOILING_LEFT, // Retroceso tras disparar hacia la izquierda + RECOILING_RIGHT, // Retroceso tras disparar hacia la derecha + // Estados de enfriamiento tras disparar COOLING_UP, // Enfriando tras disparar hacia arriba COOLING_LEFT, // Enfriando tras disparar hacia la izquierda @@ -109,9 +114,10 @@ public: bool isWaiting() const { return playing_state_ == PlayerState::WAITING; } // Getters - bool canFire() const { return cool_down_ <= 0; } + bool canFire() const { return cant_fire_counter_ <= 0; } bool hasExtraHit() const { return extra_hit_; } bool isCooling() const { return firing_state_ == PlayerState::COOLING_LEFT || firing_state_ == PlayerState::COOLING_UP || firing_state_ == PlayerState::COOLING_RIGHT; } + bool isRecoiling() const { return firing_state_ == PlayerState::RECOILING_LEFT || firing_state_ == PlayerState::RECOILING_UP || firing_state_ == PlayerState::RECOILING_RIGHT; } bool IsEligibleForHighScore() const { return score_ > Options::settings.hi_score_table.back().score; } bool isInvulnerable() const { return invulnerable_; } bool isPowerUp() const { return power_up_; } @@ -138,7 +144,7 @@ public: // Setters inline void setController(int index) { controller_index_ = index; } - void setFireCooldown(int time) { cool_down_ = time; } + void setCantFireCounter(int counter) { recoiling_state_duration_ = cant_fire_counter_ = counter; } void setFiringState(PlayerState state) { firing_state_ = state; } void setInvulnerableCounter(int value) { invulnerable_counter_ = value; } void setName(const std::string &name) { name_ = name; } @@ -156,6 +162,8 @@ private: static constexpr int WIDTH_ = 30; // Anchura static constexpr int HEIGHT_ = 30; // Altura static constexpr float BASE_SPEED_ = 1.5f; // Velocidad base del jugador + static constexpr int COOLING_DURATION_ = 30; + static constexpr int COOLING_COMPLETE_ = 0; // --- Objetos y punteros --- std::unique_ptr player_sprite_; // Sprite para dibujar el jugador @@ -171,7 +179,9 @@ private: int default_pos_y_; // Posición inicial para el jugador float vel_x_ = 0.0f; // Cantidad de píxeles a desplazarse en el eje X int vel_y_ = 0.0f; // Cantidad de píxeles a desplazarse en el eje Y - int cool_down_ = 0; // Contador durante el cual no puede disparar + int cant_fire_counter_ = 0; // Contador durante el cual no puede disparar + int recoiling_state_counter_ = 0; // Contador para la animación del estado de retroceso + int recoiling_state_duration_ = 0; // Numero de frames que dura el estado de retroceso int cooling_state_counter_ = 0; // Contador para la animación del estado cooling int score_ = 0; // Puntos del jugador float score_multiplier_ = 1.0f; // Multiplicador de puntos diff --git a/source/sections/game.cpp b/source/sections/game.cpp index 1a0e7e4..e2b7f8b 100644 --- a/source/sections/game.cpp +++ b/source/sections/game.cpp @@ -1431,37 +1431,65 @@ void Game::handleFireInput(const std::shared_ptr &player, BulletType bul { if (player->canFire()) { - player->setInput(bulletType == BulletType::UP ? InputAction::FIRE_CENTER : bulletType == BulletType::LEFT ? InputAction::FIRE_LEFT - : InputAction::FIRE_RIGHT); + switch (bulletType) + { + case BulletType::UP: + player->setInput(InputAction::FIRE_CENTER); + break; + case BulletType::LEFT: + player->setInput(InputAction::FIRE_LEFT); + break; + case BulletType::RIGHT: + player->setInput(InputAction::FIRE_RIGHT); + break; + default: + break; + } createBullet(player->getPosX() + (player->getWidth() / 2) - 6, player->getPosY() + (player->getHeight() / 2), bulletType, player->isPowerUp(), player->getId()); playSound("bullet.wav"); // Establece un tiempo de espera para el próximo disparo. - const int cooldown = player->isPowerUp() ? 5 : Options::settings.autofire ? 10 - : 7; - player->setFireCooldown(cooldown); + constexpr int POWERUP_COOLDOWN = 5; + constexpr int AUTOFIRE_COOLDOWN = 10; + constexpr int NORMAL_COOLDOWN = 7; + + int cant_fire_counter; + if (player->isPowerUp()) + { + cant_fire_counter = POWERUP_COOLDOWN; + } + else if (Options::settings.autofire) + { + cant_fire_counter = AUTOFIRE_COOLDOWN; + } + else + { + cant_fire_counter = NORMAL_COOLDOWN; + } + + player->setCantFireCounter(cant_fire_counter); } } // Gestiona las entradas de todos los jugadores en el modo normal (fuera del modo demo). void Game::handlePlayersInput() { - for (const auto &player : players_) + for (const auto &PLAYER : players_) { - if (player->isPlaying()) + if (PLAYER->isPlaying()) { // Maneja el input de los jugadores en modo normal. - handleNormalPlayerInput(player); + handleNormalPlayerInput(PLAYER); } - else if (player->isContinue() || player->isWaiting()) + else if (PLAYER->isContinue() || PLAYER->isWaiting()) { // Gestiona la continuación del jugador. - handlePlayerContinue(player); + handlePlayerContinue(PLAYER); } - else if (player->isEnteringName() || player->isEnteringNameGameCompleted() || player->isShowingName()) + else if (PLAYER->isEnteringName() || PLAYER->isEnteringNameGameCompleted() || PLAYER->isShowingName()) { // Gestiona la introducción del nombre del jugador. - handleNameInput(player); + handleNameInput(PLAYER); } } } @@ -1469,17 +1497,17 @@ void Game::handlePlayersInput() // Maneja las entradas de movimiento y disparo para un jugador en modo normal. void Game::handleNormalPlayerInput(const std::shared_ptr &player) { - const auto &controller = Options::controllers.at(player->getController()); - const bool autofire = player->isPowerUp() || Options::settings.autofire; + const auto &CONTROLLER = Options::controllers.at(player->getController()); + const bool AUTOFIRE = player->isPowerUp() || Options::settings.autofire; - if (input_->checkInput(InputAction::LEFT, INPUT_ALLOW_REPEAT, controller.type, controller.index)) + if (input_->checkInput(InputAction::LEFT, INPUT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { player->setInput(InputAction::LEFT); #ifdef RECORDING demo_.keys.left = 1; #endif } - else if (input_->checkInput(InputAction::RIGHT, INPUT_ALLOW_REPEAT, controller.type, controller.index)) + else if (input_->checkInput(InputAction::RIGHT, INPUT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { player->setInput(InputAction::RIGHT); #ifdef RECORDING @@ -1494,7 +1522,7 @@ void Game::handleNormalPlayerInput(const std::shared_ptr &player) #endif } - handleFireInputs(player, autofire, player->getController()); // Verifica y maneja todas las posibles entradas de disparo. + handleFireInputs(player, AUTOFIRE, player->getController()); // Verifica y maneja todas las posibles entradas de disparo. } // Procesa las entradas de disparo del jugador, permitiendo disparos automáticos si está habilitado. @@ -1987,9 +2015,11 @@ void Game::checkDebugEvents(const SDL_Event &event) balloon_manager_->createPowerBall(); break; } - case SDLK_2: // Crea dos globos gordos + case SDLK_2: // Activa o desactiva la aparición de globos { - balloon_manager_->createTwoBigBalloons(); + static bool deploy_balloons = true; + deploy_balloons = !deploy_balloons; + balloon_manager_->enableBalloonDeployment(deploy_balloons); break; } case SDLK_3: // Activa el modo para pasar el juego automaticamente @@ -2001,7 +2031,7 @@ void Game::checkDebugEvents(const SDL_Event &event) balloon_manager_->destroyAllBalloons(); playSound("power_ball_explosion.wav"); } - balloon_manager_->setDeployBalloons(!auto_pop_balloons_); + balloon_manager_->enableBalloonDeployment(!auto_pop_balloons_); break; } case SDLK_4: // Suelta un item