Player: afegides animacions per al estat WAITING
Player: si tires a jugar desde el estat WAITING passes al ENTERING_SCREEN i despres sempre tens inmunitat, fins i tot la primera volta (al començar el joc) falta: arregñar el z-order per al estat WAITING
This commit is contained in:
@@ -119,3 +119,10 @@ speed=5
|
||||
loop=0
|
||||
frames=47,48,49,50,51,52,53
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=hello
|
||||
speed=3
|
||||
loop=-1
|
||||
frames=54,55,56,57,58,59,60,61,62,63,64,64,64,64,64,64,64,64,64,64,64,64,64,65,66,67,68,69,70,71,72,73,73,72,71,70,70,71,72,73,73,72,71,70,70,71,72,73,73,72,71,70,70,71,72,73,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54
|
||||
[/animation]
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 14 KiB |
@@ -66,7 +66,7 @@ auto AnimatedSprite::getIndex(const std::string& name) -> int {
|
||||
|
||||
// Calcula el frame correspondiente a la animación
|
||||
void AnimatedSprite::animate() {
|
||||
if (animations_[current_animation_].speed == 0) {
|
||||
if (animations_[current_animation_].speed == 0 || animations_[current_animation_].paused) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ void AnimatedSprite::animate() {
|
||||
// En caso contrario
|
||||
else {
|
||||
// Escoge el frame correspondiente de la animación
|
||||
setSpriteClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
|
||||
updateSpriteClip();
|
||||
|
||||
// Incrementa el contador de la animacion
|
||||
animations_[current_animation_].counter++;
|
||||
@@ -110,10 +110,11 @@ void AnimatedSprite::setCurrentAnimation(const std::string& name, bool reset) {
|
||||
animations_[current_animation_].counter = 0;
|
||||
animations_[current_animation_].completed = false;
|
||||
} else {
|
||||
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size());
|
||||
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size() - 1);
|
||||
animations_[current_animation_].counter = animations_[OLD_ANIMATION].counter;
|
||||
animations_[current_animation_].completed = animations_[OLD_ANIMATION].completed;
|
||||
}
|
||||
updateSpriteClip();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,6 +133,7 @@ void AnimatedSprite::setCurrentAnimation(int index, bool reset) {
|
||||
animations_[current_animation_].counter = animations_[OLD_ANIMATION].counter;
|
||||
animations_[current_animation_].completed = animations_[OLD_ANIMATION].completed;
|
||||
}
|
||||
updateSpriteClip();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,6 +148,8 @@ void AnimatedSprite::resetAnimation() {
|
||||
animations_[current_animation_].current_frame = 0;
|
||||
animations_[current_animation_].counter = 0;
|
||||
animations_[current_animation_].completed = false;
|
||||
animations_[current_animation_].paused = false;
|
||||
updateSpriteClip();
|
||||
}
|
||||
|
||||
// Carga la animación desde un vector de cadenas
|
||||
@@ -267,3 +271,8 @@ void AnimatedSprite::parseFramesParameter(const std::string& frames_str, Animati
|
||||
void AnimatedSprite::setAnimationSpeed(size_t value) {
|
||||
animations_[current_animation_].speed = value;
|
||||
}
|
||||
|
||||
// Actualiza el spriteClip con el frame correspondiente
|
||||
void AnimatedSprite::updateSpriteClip() {
|
||||
setSpriteClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
|
||||
}
|
||||
@@ -25,6 +25,7 @@ struct Animation {
|
||||
bool completed{false}; // Indica si la animación ha finalizado
|
||||
size_t current_frame{0}; // Frame actual en reproducción
|
||||
int counter{0}; // Contador para la animación
|
||||
bool paused{false}; // La animación no avanza
|
||||
|
||||
Animation() = default;
|
||||
};
|
||||
@@ -60,6 +61,8 @@ class AnimatedSprite : public MovingSprite {
|
||||
void resetAnimation(); // Reinicia la animación actual
|
||||
void setAnimationSpeed(size_t value); // Establece la velocidad de la animación
|
||||
auto getAnimationSpeed() const -> size_t { return animations_[current_animation_].speed; } // Obtiene la velocidad de la animación actual
|
||||
void animtionPause() { animations_[current_animation_].paused = true; } // Detiene la animación
|
||||
void animationResume() { animations_[current_animation_].paused = false; } // Reanuda la animación
|
||||
|
||||
// --- Consultas ---
|
||||
auto animationIsCompleted() -> bool; // Comprueba si la animación ha terminado
|
||||
@@ -81,4 +84,5 @@ class AnimatedSprite : public MovingSprite {
|
||||
auto processAnimationBlock(const AnimationsFileBuffer& source, size_t start_index, const AnimationConfig& config) -> size_t; // Procesa un bloque completo de animación
|
||||
static void processAnimationParameter(const std::string& line, Animation& animation, const AnimationConfig& config); // Procesa un parámetro individual de animación
|
||||
static void parseFramesParameter(const std::string& frames_str, Animation& animation, const AnimationConfig& config); // Parsea el parámetro de frames (lista separada por comas)
|
||||
void updateSpriteClip(); // Actualiza el spriteClip con el frame correspondiente
|
||||
};
|
||||
@@ -30,6 +30,13 @@ MovingSprite::MovingSprite(std::shared_ptr<Texture> texture)
|
||||
|
||||
// Reinicia todas las variables
|
||||
void MovingSprite::clear() {
|
||||
stop();
|
||||
Sprite::clear();
|
||||
}
|
||||
|
||||
// Elimina el movimiento del sprite
|
||||
void MovingSprite::stop()
|
||||
{
|
||||
x_ = 0.0F; // Posición en el eje X
|
||||
y_ = 0.0F; // Posición en el eje Y
|
||||
|
||||
@@ -45,8 +52,6 @@ void MovingSprite::clear() {
|
||||
vertical_zoom_ = 1.0F; // Zoom aplicado a la altura
|
||||
|
||||
flip_ = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite
|
||||
|
||||
Sprite::clear();
|
||||
}
|
||||
|
||||
// Mueve el sprite
|
||||
|
||||
@@ -33,6 +33,7 @@ class MovingSprite : public Sprite {
|
||||
// --- Métodos principales ---
|
||||
virtual void update(); // Actualiza las variables internas del objeto
|
||||
void clear() override; // Reinicia todas las variables a cero
|
||||
void stop(); // Elimina el movimiento del sprite
|
||||
void render() override; // Muestra el sprite por pantalla
|
||||
|
||||
// --- Getters de posición y movimiento ---
|
||||
|
||||
@@ -42,9 +42,8 @@ Player::Player(int id, float x, int y, bool demo, SDL_FRect &play_area, std::vec
|
||||
void Player::init() {
|
||||
// Inicializa variables de estado
|
||||
pos_y_ = default_pos_y_;
|
||||
walking_state_ = PlayerState::WALKING_STOP;
|
||||
firing_state_ = PlayerState::FIRING_NONE;
|
||||
playing_state_ = PlayerState::WAITING;
|
||||
walking_state_ = State::WALKING_STOP;
|
||||
firing_state_ = State::FIRING_NONE;
|
||||
power_up_ = false;
|
||||
power_up_counter_ = POWERUP_COUNTER;
|
||||
extra_hit_ = false;
|
||||
@@ -73,12 +72,12 @@ void Player::init() {
|
||||
// Actua en consecuencia de la entrada recibida
|
||||
void Player::setInput(InputAction input) {
|
||||
switch (playing_state_) {
|
||||
case PlayerState::PLAYING: {
|
||||
case State::PLAYING: {
|
||||
setInputPlaying(input);
|
||||
break;
|
||||
}
|
||||
case PlayerState::ENTERING_NAME:
|
||||
case PlayerState::ENTERING_NAME_GAME_COMPLETED: {
|
||||
case State::ENTERING_NAME:
|
||||
case State::ENTERING_NAME_GAME_COMPLETED: {
|
||||
setInputEnteringName(input);
|
||||
break;
|
||||
}
|
||||
@@ -92,29 +91,29 @@ void Player::setInputPlaying(InputAction input) {
|
||||
switch (input) {
|
||||
case InputAction::LEFT: {
|
||||
vel_x_ = -BASE_SPEED;
|
||||
setWalkingState(PlayerState::WALKING_LEFT);
|
||||
setWalkingState(State::WALKING_LEFT);
|
||||
break;
|
||||
}
|
||||
case InputAction::RIGHT: {
|
||||
vel_x_ = BASE_SPEED;
|
||||
setWalkingState(PlayerState::WALKING_RIGHT);
|
||||
setWalkingState(State::WALKING_RIGHT);
|
||||
break;
|
||||
}
|
||||
case InputAction::FIRE_CENTER: {
|
||||
setFiringState(PlayerState::FIRING_UP);
|
||||
setFiringState(State::FIRING_UP);
|
||||
break;
|
||||
}
|
||||
case InputAction::FIRE_LEFT: {
|
||||
setFiringState(PlayerState::FIRING_LEFT);
|
||||
setFiringState(State::FIRING_LEFT);
|
||||
break;
|
||||
}
|
||||
case InputAction::FIRE_RIGHT: {
|
||||
setFiringState(PlayerState::FIRING_RIGHT);
|
||||
setFiringState(State::FIRING_RIGHT);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
vel_x_ = 0;
|
||||
setWalkingState(PlayerState::WALKING_STOP);
|
||||
setWalkingState(State::WALKING_STOP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -147,27 +146,30 @@ void Player::setInputEnteringName(InputAction input) {
|
||||
// Mueve el jugador a la posición y animación que le corresponde
|
||||
void Player::move() {
|
||||
switch (playing_state_) {
|
||||
case PlayerState::PLAYING:
|
||||
case State::PLAYING:
|
||||
handlePlayingMovement();
|
||||
break;
|
||||
case PlayerState::ROLLING:
|
||||
case State::ROLLING:
|
||||
handleRollingMovement();
|
||||
break;
|
||||
case PlayerState::TITLE_ANIMATION:
|
||||
case State::TITLE_ANIMATION:
|
||||
handleTitleAnimation();
|
||||
break;
|
||||
case PlayerState::CONTINUE_TIME_OUT:
|
||||
case State::CONTINUE_TIME_OUT:
|
||||
handleContinueTimeOut();
|
||||
break;
|
||||
case PlayerState::LEAVING_SCREEN:
|
||||
case State::LEAVING_SCREEN:
|
||||
handleLeavingScreen();
|
||||
break;
|
||||
case PlayerState::ENTERING_SCREEN:
|
||||
case State::ENTERING_SCREEN:
|
||||
handleEnteringScreen();
|
||||
break;
|
||||
case PlayerState::CREDITS:
|
||||
case State::CREDITS:
|
||||
handleCreditsMovement();
|
||||
break;
|
||||
case State::WAITING:
|
||||
handleWaitingMovement();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -215,9 +217,9 @@ void Player::handleRollingGroundCollision() {
|
||||
}
|
||||
|
||||
void Player::handleRollingStop() {
|
||||
const auto NEXT_PLAYER_STATUS = isEligibleForHighScore() ? PlayerState::ENTERING_NAME : PlayerState::CONTINUE;
|
||||
const auto NEXT_PLAYER_STATUS = isEligibleForHighScore() ? State::ENTERING_NAME : State::CONTINUE;
|
||||
|
||||
const auto NEXT_STATE = demo_ ? PlayerState::LYING_ON_THE_FLOOR_FOREVER : NEXT_PLAYER_STATUS;
|
||||
const auto NEXT_STATE = demo_ ? State::LYING_ON_THE_FLOOR_FOREVER : NEXT_PLAYER_STATUS;
|
||||
|
||||
setPlayingState(NEXT_STATE);
|
||||
pos_x_ = player_sprite_->getPosX();
|
||||
@@ -245,14 +247,15 @@ void Player::handleTitleAnimation() {
|
||||
shiftSprite();
|
||||
|
||||
if (pos_x_ == MIN_X || pos_x_ == MAX_X) {
|
||||
setPlayingState(PlayerState::TITLE_HIDDEN);
|
||||
setPlayingState(State::TITLE_HIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::handleContinueTimeOut() {
|
||||
// Si el cadaver desaparece por el suelo, cambia de estado
|
||||
if (player_sprite_->getPosY() > play_area_.h) {
|
||||
setPlayingState(PlayerState::WAITING);
|
||||
player_sprite_->stop();
|
||||
setPlayingState(State::WAITING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,7 +270,7 @@ void Player::handleLeavingScreen() {
|
||||
shiftSprite();
|
||||
|
||||
if (pos_x_ == MIN_X || pos_x_ == MAX_X) {
|
||||
setPlayingState(PlayerState::GAME_OVER);
|
||||
setPlayingState(State::GAME_OVER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,8 +291,7 @@ void Player::handlePlayer1Entering() {
|
||||
pos_x_ += vel_x_;
|
||||
if (pos_x_ > default_pos_x_) {
|
||||
pos_x_ = default_pos_x_;
|
||||
setPlayingState(PlayerState::PLAYING);
|
||||
setInvulnerable(false);
|
||||
setPlayingState(State::RESPAWNING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,8 +300,7 @@ void Player::handlePlayer2Entering() {
|
||||
pos_x_ += vel_x_;
|
||||
if (pos_x_ < default_pos_x_) {
|
||||
pos_x_ = default_pos_x_;
|
||||
setPlayingState(PlayerState::PLAYING);
|
||||
setInvulnerable(false);
|
||||
setPlayingState(State::RESPAWNING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,11 +331,19 @@ void Player::handleCreditsLeftMovement() {
|
||||
}
|
||||
}
|
||||
|
||||
void Player::handleWaitingMovement() {
|
||||
++waiting_counter_;
|
||||
if (waiting_counter_ == WAITING_COUNTER) {
|
||||
waiting_counter_ = 0;
|
||||
player_sprite_->resetAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
void Player::updateWalkingStateForCredits() {
|
||||
if (pos_x_ > param.game.game_area.center_x - WIDTH / 2) {
|
||||
setWalkingState(PlayerState::WALKING_LEFT);
|
||||
setWalkingState(State::WALKING_LEFT);
|
||||
} else {
|
||||
setWalkingState(PlayerState::WALKING_RIGHT);
|
||||
setWalkingState(State::WALKING_RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,25 +383,25 @@ void Player::render() {
|
||||
// Establece la animación correspondiente al estado
|
||||
void Player::setAnimation() {
|
||||
switch (playing_state_) {
|
||||
case PlayerState::PLAYING:
|
||||
case PlayerState::ENTERING_NAME_GAME_COMPLETED:
|
||||
case PlayerState::ENTERING_SCREEN:
|
||||
case PlayerState::LEAVING_SCREEN:
|
||||
case PlayerState::TITLE_ANIMATION:
|
||||
case PlayerState::CREDITS: {
|
||||
case State::PLAYING:
|
||||
case State::ENTERING_NAME_GAME_COMPLETED:
|
||||
case State::ENTERING_SCREEN:
|
||||
case State::LEAVING_SCREEN:
|
||||
case State::TITLE_ANIMATION:
|
||||
case State::CREDITS: {
|
||||
// Crea cadenas de texto para componer el nombre de la animación
|
||||
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 std::string WALK_ANIMATION = walking_state_ == State::WALKING_STOP ? "stand" : "walk";
|
||||
const std::string FIRE_ANIMATION = firing_state_ == State::FIRING_UP ? "-fire-center" : "-fire-side";
|
||||
const std::string RECOIL_ANIMATION = firing_state_ == State::RECOILING_UP ? "-recoil-center" : "-recoil-side";
|
||||
const std::string COOL_ANIMATION = firing_state_ == State::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_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;
|
||||
const SDL_FlipMode FLIP_WALK = walking_state_ == State::WALKING_RIGHT ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
|
||||
const SDL_FlipMode FLIP_FIRE = firing_state_ == State::FIRING_RIGHT ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
|
||||
const SDL_FlipMode FLIP_RECOIL = firing_state_ == State::RECOILING_RIGHT ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
|
||||
const SDL_FlipMode FLIP_COOL = firing_state_ == State::COOLING_RIGHT ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
|
||||
|
||||
// Establece la animación a partir de las cadenas
|
||||
if (firing_state_ == PlayerState::FIRING_NONE) {
|
||||
if (firing_state_ == State::FIRING_NONE) {
|
||||
// No esta disparando
|
||||
player_sprite_->setCurrentAnimation(WALK_ANIMATION, false);
|
||||
player_sprite_->setFlip(FLIP_WALK);
|
||||
@@ -413,18 +422,22 @@ void Player::setAnimation() {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PlayerState::ROLLING:
|
||||
case PlayerState::CONTINUE_TIME_OUT: {
|
||||
case State::WAITING: {
|
||||
player_sprite_->setCurrentAnimation("hello");
|
||||
break;
|
||||
}
|
||||
case State::ROLLING:
|
||||
case State::CONTINUE_TIME_OUT: {
|
||||
player_sprite_->setCurrentAnimation("rolling");
|
||||
break;
|
||||
}
|
||||
case PlayerState::LYING_ON_THE_FLOOR_FOREVER:
|
||||
case PlayerState::ENTERING_NAME:
|
||||
case PlayerState::CONTINUE: {
|
||||
case State::LYING_ON_THE_FLOOR_FOREVER:
|
||||
case State::ENTERING_NAME:
|
||||
case State::CONTINUE: {
|
||||
player_sprite_->setCurrentAnimation("dead");
|
||||
break;
|
||||
}
|
||||
case PlayerState::CELEBRATING: {
|
||||
case State::CELEBRATING: {
|
||||
player_sprite_->setCurrentAnimation("celebration");
|
||||
break;
|
||||
}
|
||||
@@ -439,7 +452,7 @@ void Player::setAnimation() {
|
||||
|
||||
// Actualiza el valor de la variable
|
||||
void Player::updateCooldown() {
|
||||
if (playing_state_ != PlayerState::PLAYING) {
|
||||
if (playing_state_ != State::PLAYING) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -488,14 +501,14 @@ void Player::handleCoolingState() {
|
||||
|
||||
void Player::transitionToRecoiling() {
|
||||
switch (firing_state_) {
|
||||
case PlayerState::FIRING_LEFT:
|
||||
setFiringState(PlayerState::RECOILING_LEFT);
|
||||
case State::FIRING_LEFT:
|
||||
setFiringState(State::RECOILING_LEFT);
|
||||
break;
|
||||
case PlayerState::FIRING_RIGHT:
|
||||
setFiringState(PlayerState::RECOILING_RIGHT);
|
||||
case State::FIRING_RIGHT:
|
||||
setFiringState(State::RECOILING_RIGHT);
|
||||
break;
|
||||
case PlayerState::FIRING_UP:
|
||||
setFiringState(PlayerState::RECOILING_UP);
|
||||
case State::FIRING_UP:
|
||||
setFiringState(State::RECOILING_UP);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -504,14 +517,14 @@ void Player::transitionToRecoiling() {
|
||||
|
||||
void Player::transitionToCooling() {
|
||||
switch (firing_state_) {
|
||||
case PlayerState::RECOILING_LEFT:
|
||||
setFiringState(PlayerState::COOLING_LEFT);
|
||||
case State::RECOILING_LEFT:
|
||||
setFiringState(State::COOLING_LEFT);
|
||||
break;
|
||||
case PlayerState::RECOILING_RIGHT:
|
||||
setFiringState(PlayerState::COOLING_RIGHT);
|
||||
case State::RECOILING_RIGHT:
|
||||
setFiringState(State::COOLING_RIGHT);
|
||||
break;
|
||||
case PlayerState::RECOILING_UP:
|
||||
setFiringState(PlayerState::COOLING_UP);
|
||||
case State::RECOILING_UP:
|
||||
setFiringState(State::COOLING_UP);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -519,7 +532,7 @@ void Player::transitionToCooling() {
|
||||
}
|
||||
|
||||
void Player::completeCooling() {
|
||||
setFiringState(PlayerState::FIRING_NONE);
|
||||
setFiringState(State::FIRING_NONE);
|
||||
cooling_state_counter_ = -1;
|
||||
}
|
||||
|
||||
@@ -547,14 +560,14 @@ void Player::addScore(int score) {
|
||||
// Actualiza el panel del marcador
|
||||
void Player::updateScoreboard() {
|
||||
switch (playing_state_) {
|
||||
case PlayerState::CONTINUE: {
|
||||
Scoreboard::get()->setContinue(getScoreBoardPanel(), getContinueCounter());
|
||||
case State::CONTINUE: {
|
||||
Scoreboard::get()->setContinue(scoreboard_panel_, getContinueCounter());
|
||||
break;
|
||||
}
|
||||
case PlayerState::ENTERING_NAME:
|
||||
case PlayerState::ENTERING_NAME_GAME_COMPLETED: {
|
||||
Scoreboard::get()->setRecordName(getScoreBoardPanel(), enter_name_->getCurrentName());
|
||||
Scoreboard::get()->setSelectorPos(getScoreBoardPanel(), getRecordNamePos());
|
||||
case State::ENTERING_NAME:
|
||||
case State::ENTERING_NAME_GAME_COMPLETED: {
|
||||
Scoreboard::get()->setRecordName(scoreboard_panel_, enter_name_->getCurrentName());
|
||||
Scoreboard::get()->setSelectorPos(scoreboard_panel_, getRecordNamePos());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -563,55 +576,70 @@ void Player::updateScoreboard() {
|
||||
}
|
||||
|
||||
// Cambia el modo del marcador
|
||||
void Player::setScoreboardMode(ScoreboardMode mode) const {
|
||||
void Player::setScoreboardMode(Scoreboard::Mode mode) const {
|
||||
if (!demo_) {
|
||||
Scoreboard::get()->setMode(getScoreBoardPanel(), mode);
|
||||
Scoreboard::get()->setMode(scoreboard_panel_, mode);
|
||||
}
|
||||
}
|
||||
|
||||
// Establece el estado del jugador en el juego
|
||||
void Player::setPlayingState(PlayerState state) {
|
||||
void Player::setPlayingState(State state) {
|
||||
playing_state_ = state;
|
||||
|
||||
switch (playing_state_) {
|
||||
case PlayerState::RESPAWNING: {
|
||||
case State::RESPAWNING: {
|
||||
setInvulnerable(true);
|
||||
addCredit();
|
||||
playSound("voice_thankyou.wav");
|
||||
setPlayingState(PlayerState::PLAYING);
|
||||
setPlayingState(State::PLAYING);
|
||||
}
|
||||
case PlayerState::PLAYING: {
|
||||
case State::PLAYING: {
|
||||
init();
|
||||
playing_state_ = PlayerState::PLAYING;
|
||||
setScoreboardMode(ScoreboardMode::SCORE);
|
||||
playing_state_ = State::PLAYING;
|
||||
setScoreboardMode(Scoreboard::Mode::SCORE);
|
||||
Stage::power_can_be_added = true;
|
||||
break;
|
||||
}
|
||||
case PlayerState::CONTINUE: {
|
||||
case State::CONTINUE: {
|
||||
// Inicializa el contador de continuar
|
||||
continue_ticks_ = SDL_GetTicks();
|
||||
continue_counter_ = 9;
|
||||
setScoreboardMode(ScoreboardMode::CONTINUE);
|
||||
setScoreboardMode(Scoreboard::Mode::CONTINUE);
|
||||
playSound("continue_clock.wav");
|
||||
break;
|
||||
}
|
||||
case PlayerState::WAITING: {
|
||||
pos_x_ = default_pos_x_;
|
||||
setScoreboardMode(ScoreboardMode::WAITING);
|
||||
case State::WAITING: {
|
||||
switch (id_) {
|
||||
case 1:
|
||||
pos_x_ = param.game.game_area.rect.x;
|
||||
break;
|
||||
case 2:
|
||||
pos_x_ = param.game.game_area.rect.w - WIDTH;
|
||||
break;
|
||||
default:
|
||||
pos_x_ = 0;
|
||||
break;
|
||||
}
|
||||
pos_y_ = default_pos_y_;
|
||||
waiting_counter_ = 0;
|
||||
shiftSprite();
|
||||
player_sprite_->setCurrentAnimation("hello");
|
||||
player_sprite_->animtionPause();
|
||||
setScoreboardMode(Scoreboard::Mode::WAITING);
|
||||
break;
|
||||
}
|
||||
case PlayerState::ENTERING_NAME: {
|
||||
setScoreboardMode(ScoreboardMode::ENTER_NAME);
|
||||
case State::ENTERING_NAME: {
|
||||
setScoreboardMode(Scoreboard::Mode::ENTER_NAME);
|
||||
break;
|
||||
}
|
||||
case PlayerState::SHOWING_NAME: {
|
||||
case State::SHOWING_NAME: {
|
||||
showing_name_ticks_ = SDL_GetTicks();
|
||||
setScoreboardMode(ScoreboardMode::SHOW_NAME);
|
||||
setScoreboardMode(Scoreboard::Mode::SHOW_NAME);
|
||||
Scoreboard::get()->setRecordName(scoreboard_panel_, last_enter_name_);
|
||||
addScoreToScoreBoard();
|
||||
break;
|
||||
}
|
||||
case PlayerState::ROLLING: {
|
||||
case State::ROLLING: {
|
||||
// Activa la animación de rodar
|
||||
player_sprite_->setCurrentAnimation("rolling");
|
||||
player_sprite_->setAnimationSpeed(4);
|
||||
@@ -620,52 +648,52 @@ void Player::setPlayingState(PlayerState state) {
|
||||
(rand() % 2 == 0) ? player_sprite_->setVelX(3.3F) : player_sprite_->setVelX(-3.3F);
|
||||
break;
|
||||
}
|
||||
case PlayerState::TITLE_ANIMATION: {
|
||||
case State::TITLE_ANIMATION: {
|
||||
// Activa la animación de rodar
|
||||
player_sprite_->setCurrentAnimation("walk");
|
||||
playSound("voice_thankyou.wav");
|
||||
break;
|
||||
}
|
||||
case PlayerState::TITLE_HIDDEN: {
|
||||
case State::TITLE_HIDDEN: {
|
||||
player_sprite_->setVelX(0.0F);
|
||||
player_sprite_->setVelY(0.0F);
|
||||
break;
|
||||
}
|
||||
case PlayerState::CONTINUE_TIME_OUT: {
|
||||
case State::CONTINUE_TIME_OUT: {
|
||||
// Activa la animación de morir
|
||||
player_sprite_->setAccelY(0.2F);
|
||||
player_sprite_->setVelY(-4.0F);
|
||||
player_sprite_->setVelX(0.0F);
|
||||
player_sprite_->setCurrentAnimation("rolling");
|
||||
player_sprite_->setAnimationSpeed(5);
|
||||
setScoreboardMode(ScoreboardMode::GAME_OVER);
|
||||
setScoreboardMode(Scoreboard::Mode::GAME_OVER);
|
||||
playSound("voice_aw_aw_aw.wav");
|
||||
playSound("jump.wav");
|
||||
break;
|
||||
}
|
||||
case PlayerState::GAME_OVER: {
|
||||
setScoreboardMode(ScoreboardMode::GAME_OVER);
|
||||
case State::GAME_OVER: {
|
||||
setScoreboardMode(Scoreboard::Mode::GAME_OVER);
|
||||
break;
|
||||
}
|
||||
case PlayerState::CELEBRATING: {
|
||||
case State::CELEBRATING: {
|
||||
game_completed_ = true;
|
||||
setScoreboardMode(ScoreboardMode::SCORE);
|
||||
setScoreboardMode(Scoreboard::Mode::SCORE);
|
||||
break;
|
||||
}
|
||||
case PlayerState::ENTERING_NAME_GAME_COMPLETED: {
|
||||
setWalkingState(PlayerState::WALKING_STOP);
|
||||
setFiringState(PlayerState::FIRING_NONE);
|
||||
setScoreboardMode(ScoreboardMode::ENTER_NAME);
|
||||
case State::ENTERING_NAME_GAME_COMPLETED: {
|
||||
setWalkingState(State::WALKING_STOP);
|
||||
setFiringState(State::FIRING_NONE);
|
||||
setScoreboardMode(Scoreboard::Mode::ENTER_NAME);
|
||||
break;
|
||||
}
|
||||
case PlayerState::LEAVING_SCREEN: {
|
||||
case State::LEAVING_SCREEN: {
|
||||
step_counter_ = 0;
|
||||
setScoreboardMode(ScoreboardMode::GAME_COMPLETED);
|
||||
setScoreboardMode(Scoreboard::Mode::GAME_COMPLETED);
|
||||
break;
|
||||
}
|
||||
case PlayerState::ENTERING_SCREEN: {
|
||||
case State::ENTERING_SCREEN: {
|
||||
step_counter_ = 0;
|
||||
setScoreboardMode(ScoreboardMode::SCORE);
|
||||
setScoreboardMode(Scoreboard::Mode::SCORE);
|
||||
switch (id_) {
|
||||
case 1:
|
||||
pos_x_ = param.game.game_area.rect.x - WIDTH;
|
||||
@@ -680,8 +708,8 @@ void Player::setPlayingState(PlayerState state) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PlayerState::CREDITS: {
|
||||
vel_x_ = (walking_state_ == PlayerState::WALKING_RIGHT) ? BASE_SPEED : -BASE_SPEED;
|
||||
case State::CREDITS: {
|
||||
vel_x_ = (walking_state_ == State::WALKING_RIGHT) ? BASE_SPEED : -BASE_SPEED;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -709,7 +737,7 @@ void Player::setInvulnerable(bool value) {
|
||||
|
||||
// Monitoriza el estado
|
||||
void Player::updateInvulnerable() {
|
||||
if (playing_state_ == PlayerState::PLAYING) {
|
||||
if (playing_state_ == State::PLAYING) {
|
||||
if (invulnerable_) {
|
||||
if (invulnerable_counter_ > 0) {
|
||||
--invulnerable_counter_;
|
||||
@@ -730,7 +758,7 @@ void Player::setPowerUp() {
|
||||
|
||||
// Actualiza el valor de la variable
|
||||
void Player::updatePowerUp() {
|
||||
if (playing_state_ == PlayerState::PLAYING) {
|
||||
if (playing_state_ == State::PLAYING) {
|
||||
if (power_up_) {
|
||||
--power_up_counter_;
|
||||
power_up_ = power_up_counter_ > 0;
|
||||
@@ -772,7 +800,7 @@ void Player::setPlayerTextures(const std::vector<std::shared_ptr<Texture>> &text
|
||||
|
||||
// Actualiza el contador de continue
|
||||
void Player::updateContinueCounter() {
|
||||
if (playing_state_ == PlayerState::CONTINUE) {
|
||||
if (playing_state_ == State::CONTINUE) {
|
||||
constexpr int TICKS_SPEED = 1000;
|
||||
if (SDL_GetTicks() - continue_ticks_ > TICKS_SPEED) {
|
||||
decContinueCounter();
|
||||
@@ -782,7 +810,7 @@ void Player::updateContinueCounter() {
|
||||
|
||||
// Actualiza el contador de entrar nombre
|
||||
void Player::updateEnterNameCounter() {
|
||||
if (playing_state_ == PlayerState::ENTERING_NAME || playing_state_ == PlayerState::ENTERING_NAME_GAME_COMPLETED) {
|
||||
if (playing_state_ == State::ENTERING_NAME || playing_state_ == State::ENTERING_NAME_GAME_COMPLETED) {
|
||||
constexpr int TICKS_SPEED = 1000;
|
||||
if (SDL_GetTicks() - name_entry_ticks_ > TICKS_SPEED) {
|
||||
decNameEntryCounter();
|
||||
@@ -792,10 +820,10 @@ void Player::updateEnterNameCounter() {
|
||||
|
||||
// Actualiza el estado de SHOWING_NAME
|
||||
void Player::updateShowingName() {
|
||||
if (playing_state_ == PlayerState::SHOWING_NAME) {
|
||||
if (playing_state_ == State::SHOWING_NAME) {
|
||||
constexpr int TICKS_SPEED = 5000;
|
||||
if (SDL_GetTicks() - name_entry_ticks_ > TICKS_SPEED) {
|
||||
game_completed_ ? setPlayingState(PlayerState::LEAVING_SCREEN) : setPlayingState(PlayerState::CONTINUE);
|
||||
game_completed_ ? setPlayingState(State::LEAVING_SCREEN) : setPlayingState(State::CONTINUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -805,7 +833,7 @@ void Player::decContinueCounter() {
|
||||
continue_ticks_ = SDL_GetTicks();
|
||||
--continue_counter_;
|
||||
if (continue_counter_ < 0) {
|
||||
setPlayingState(PlayerState::CONTINUE_TIME_OUT);
|
||||
setPlayingState(State::CONTINUE_TIME_OUT);
|
||||
} else {
|
||||
playSound("continue_clock.wav");
|
||||
}
|
||||
@@ -824,11 +852,11 @@ void Player::decNameEntryCounter() {
|
||||
(name_entry_idle_counter_ >= param.game.name_entry_idle_time)) {
|
||||
name_entry_total_counter_ = 0;
|
||||
name_entry_idle_counter_ = 0;
|
||||
if (playing_state_ == PlayerState::ENTERING_NAME) {
|
||||
if (playing_state_ == State::ENTERING_NAME) {
|
||||
last_enter_name_ = getRecordName();
|
||||
setPlayingState(PlayerState::SHOWING_NAME);
|
||||
setPlayingState(State::SHOWING_NAME);
|
||||
} else {
|
||||
setPlayingState(PlayerState::LEAVING_SCREEN);
|
||||
setPlayingState(State::LEAVING_SCREEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -861,7 +889,7 @@ void Player::playSound(const std::string &name) const {
|
||||
|
||||
// Indica si se puede dibujar el objeto
|
||||
auto Player::isRenderable() const -> bool {
|
||||
return !isWaiting() && !isGameOver() && !isTitleHidden();
|
||||
return !isGameOver() && !isTitleHidden();
|
||||
};
|
||||
|
||||
// Añade una puntuación a la tabla de records
|
||||
|
||||
298
source/player.h
298
source/player.h
@@ -10,58 +10,59 @@
|
||||
#include "enter_name.h" // Para EnterName
|
||||
#include "manage_hiscore_table.h" // Para HiScoreEntry
|
||||
#include "options.h" // Para SettingsOptions, settings
|
||||
#include "scoreboard.h" // Para Scoreboard
|
||||
#include "utils.h" // Para Circle
|
||||
|
||||
class Texture;
|
||||
enum class InputAction : int;
|
||||
enum class ScoreboardMode;
|
||||
|
||||
// --- Estados posibles del jugador ---
|
||||
enum class PlayerState {
|
||||
// Estados de movimiento
|
||||
WALKING_LEFT, // Caminando hacia la izquierda
|
||||
WALKING_RIGHT, // Caminando hacia la derecha
|
||||
WALKING_STOP, // Parado, sin moverse
|
||||
|
||||
// Estados de disparo
|
||||
FIRING_UP, // Disparando hacia arriba
|
||||
FIRING_LEFT, // Disparando hacia la izquierda
|
||||
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
|
||||
COOLING_RIGHT, // Enfriando tras disparar hacia la derecha
|
||||
|
||||
// Estados generales del jugador
|
||||
PLAYING, // Está jugando activamente
|
||||
CONTINUE, // Cuenta atrás para continuar tras perder
|
||||
CONTINUE_TIME_OUT, // Se ha terminado la cuenta atras para continuar y se retira al jugador de la zona de juego
|
||||
WAITING, // Esperando para entrar a jugar
|
||||
ENTERING_NAME, // Introduciendo nombre para la tabla de puntuaciones
|
||||
SHOWING_NAME, // Mostrando el nombre introducido
|
||||
ROLLING, // El jugador está muriendo (animación de muerte)
|
||||
LYING_ON_THE_FLOOR_FOREVER, // El jugador está inconsciente para siempre en el suelo (demo)
|
||||
GAME_OVER, // Fin de la partida, no puede jugar
|
||||
CELEBRATING, // Celebrando victoria (pose de victoria)
|
||||
ENTERING_NAME_GAME_COMPLETED, // Introduciendo nombre tras completar el juego
|
||||
LEAVING_SCREEN, // Saliendo de la pantalla (animación)
|
||||
ENTERING_SCREEN, // Entrando a la pantalla (animación)
|
||||
CREDITS, // Estado para mostrar los créditos del juego
|
||||
TITLE_ANIMATION, // Animacion para el titulo
|
||||
TITLE_HIDDEN, // Animacion para el titulo
|
||||
RESPAWNING, // Tras continuar y volver al juego
|
||||
};
|
||||
enum class Mode;
|
||||
|
||||
// --- Clase Player ---
|
||||
class Player {
|
||||
public:
|
||||
// --- Estados posibles del jugador ---
|
||||
enum class State {
|
||||
// Estados de movimiento
|
||||
WALKING_LEFT, // Caminando hacia la izquierda
|
||||
WALKING_RIGHT, // Caminando hacia la derecha
|
||||
WALKING_STOP, // Parado, sin moverse
|
||||
|
||||
// Estados de disparo
|
||||
FIRING_UP, // Disparando hacia arriba
|
||||
FIRING_LEFT, // Disparando hacia la izquierda
|
||||
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
|
||||
COOLING_RIGHT, // Enfriando tras disparar hacia la derecha
|
||||
|
||||
// Estados generales del jugador
|
||||
PLAYING, // Está jugando activamente
|
||||
CONTINUE, // Cuenta atrás para continuar tras perder
|
||||
CONTINUE_TIME_OUT, // Se ha terminado la cuenta atras para continuar y se retira al jugador de la zona de juego
|
||||
WAITING, // Esperando para entrar a jugar
|
||||
ENTERING_NAME, // Introduciendo nombre para la tabla de puntuaciones
|
||||
SHOWING_NAME, // Mostrando el nombre introducido
|
||||
ROLLING, // El jugador está muriendo (animación de muerte)
|
||||
LYING_ON_THE_FLOOR_FOREVER, // El jugador está inconsciente para siempre en el suelo (demo)
|
||||
GAME_OVER, // Fin de la partida, no puede jugar
|
||||
CELEBRATING, // Celebrando victoria (pose de victoria)
|
||||
ENTERING_NAME_GAME_COMPLETED, // Introduciendo nombre tras completar el juego
|
||||
LEAVING_SCREEN, // Saliendo de la pantalla (animación)
|
||||
ENTERING_SCREEN, // Entrando a la pantalla (animación)
|
||||
CREDITS, // Estado para mostrar los créditos del juego
|
||||
TITLE_ANIMATION, // Animacion para el titulo
|
||||
TITLE_HIDDEN, // Animacion para el titulo
|
||||
RESPAWNING, // Tras continuar y volver al juego
|
||||
};
|
||||
|
||||
// --- Constructor y destructor ---
|
||||
Player(int id, float x, int y, bool demo, SDL_FRect &play_area, std::vector<std::shared_ptr<Texture>> texture, const std::vector<std::vector<std::string>> &animations);
|
||||
~Player() = default;
|
||||
@@ -92,36 +93,36 @@ class Player {
|
||||
void decScoreMultiplier(); // Decrementa el multiplicador
|
||||
|
||||
// --- Estados de juego ---
|
||||
void setPlayingState(PlayerState state); // Cambia el estado de juego
|
||||
void setInvulnerable(bool value); // Establece el valor del estado de invulnerabilidad
|
||||
void setPowerUp(); // Activa el modo PowerUp
|
||||
void updatePowerUp(); // Actualiza el valor de PowerUp
|
||||
void giveExtraHit(); // Concede un toque extra al jugador
|
||||
void removeExtraHit(); // Quita el toque extra al jugador
|
||||
void decContinueCounter(); // Decrementa el contador de continuar
|
||||
void setPlayingState(State state); // Cambia el estado de juego
|
||||
void setInvulnerable(bool value); // Establece el valor del estado de invulnerabilidad
|
||||
void setPowerUp(); // Activa el modo PowerUp
|
||||
void updatePowerUp(); // Actualiza el valor de PowerUp
|
||||
void giveExtraHit(); // Concede un toque extra al jugador
|
||||
void removeExtraHit(); // Quita el toque extra al jugador
|
||||
void decContinueCounter(); // Decrementa el contador de continuar
|
||||
|
||||
// --- Getters y comprobaciones de estado ---
|
||||
[[nodiscard]] auto getRecordNamePos() const -> int; // Obtiene la posición que se está editando del nombre del jugador para la tabla de mejores puntuaciones
|
||||
|
||||
// Comprobación de playing_state
|
||||
[[nodiscard]] auto isLyingOnTheFloorForever() const -> bool { return playing_state_ == PlayerState::LYING_ON_THE_FLOOR_FOREVER; }
|
||||
[[nodiscard]] auto isCelebrating() const -> bool { return playing_state_ == PlayerState::CELEBRATING; }
|
||||
[[nodiscard]] auto isContinue() const -> bool { return playing_state_ == PlayerState::CONTINUE; }
|
||||
[[nodiscard]] auto isDying() const -> bool { return playing_state_ == PlayerState::ROLLING; }
|
||||
[[nodiscard]] auto isEnteringName() const -> bool { return playing_state_ == PlayerState::ENTERING_NAME; }
|
||||
[[nodiscard]] auto isShowingName() const -> bool { return playing_state_ == PlayerState::SHOWING_NAME; }
|
||||
[[nodiscard]] auto isEnteringNameGameCompleted() const -> bool { return playing_state_ == PlayerState::ENTERING_NAME_GAME_COMPLETED; }
|
||||
[[nodiscard]] auto isLeavingScreen() const -> bool { return playing_state_ == PlayerState::LEAVING_SCREEN; }
|
||||
[[nodiscard]] auto isGameOver() const -> bool { return playing_state_ == PlayerState::GAME_OVER; }
|
||||
[[nodiscard]] auto isPlaying() const -> bool { return playing_state_ == PlayerState::PLAYING; }
|
||||
[[nodiscard]] auto isWaiting() const -> bool { return playing_state_ == PlayerState::WAITING; }
|
||||
[[nodiscard]] auto isTitleHidden() const -> bool { return playing_state_ == PlayerState::TITLE_HIDDEN; }
|
||||
[[nodiscard]] auto isLyingOnTheFloorForever() const -> bool { return playing_state_ == State::LYING_ON_THE_FLOOR_FOREVER; }
|
||||
[[nodiscard]] auto isCelebrating() const -> bool { return playing_state_ == State::CELEBRATING; }
|
||||
[[nodiscard]] auto isContinue() const -> bool { return playing_state_ == State::CONTINUE; }
|
||||
[[nodiscard]] auto isDying() const -> bool { return playing_state_ == State::ROLLING; }
|
||||
[[nodiscard]] auto isEnteringName() const -> bool { return playing_state_ == State::ENTERING_NAME; }
|
||||
[[nodiscard]] auto isShowingName() const -> bool { return playing_state_ == State::SHOWING_NAME; }
|
||||
[[nodiscard]] auto isEnteringNameGameCompleted() const -> bool { return playing_state_ == State::ENTERING_NAME_GAME_COMPLETED; }
|
||||
[[nodiscard]] auto isLeavingScreen() const -> bool { return playing_state_ == State::LEAVING_SCREEN; }
|
||||
[[nodiscard]] auto isGameOver() const -> bool { return playing_state_ == State::GAME_OVER; }
|
||||
[[nodiscard]] auto isPlaying() const -> bool { return playing_state_ == State::PLAYING; }
|
||||
[[nodiscard]] auto isWaiting() const -> bool { return playing_state_ == State::WAITING; }
|
||||
[[nodiscard]] auto isTitleHidden() const -> bool { return playing_state_ == State::TITLE_HIDDEN; }
|
||||
|
||||
// Getters
|
||||
[[nodiscard]] auto canFire() const -> bool { return cant_fire_counter_ <= 0; }
|
||||
[[nodiscard]] auto hasExtraHit() const -> bool { return extra_hit_; }
|
||||
[[nodiscard]] auto isCooling() const -> bool { return firing_state_ == PlayerState::COOLING_LEFT || firing_state_ == PlayerState::COOLING_UP || firing_state_ == PlayerState::COOLING_RIGHT; }
|
||||
[[nodiscard]] auto isRecoiling() const -> bool { return firing_state_ == PlayerState::RECOILING_LEFT || firing_state_ == PlayerState::RECOILING_UP || firing_state_ == PlayerState::RECOILING_RIGHT; }
|
||||
[[nodiscard]] auto isCooling() const -> bool { return firing_state_ == State::COOLING_LEFT || firing_state_ == State::COOLING_UP || firing_state_ == State::COOLING_RIGHT; }
|
||||
[[nodiscard]] auto isRecoiling() const -> bool { return firing_state_ == State::RECOILING_LEFT || firing_state_ == State::RECOILING_UP || firing_state_ == State::RECOILING_RIGHT; }
|
||||
[[nodiscard]] auto isEligibleForHighScore() const -> bool { return score_ > Options::settings.hi_score_table.back().score; }
|
||||
[[nodiscard]] auto isInvulnerable() const -> bool { return invulnerable_; }
|
||||
[[nodiscard]] auto isPowerUp() const -> bool { return power_up_; }
|
||||
@@ -139,9 +140,9 @@ class Player {
|
||||
[[nodiscard]] auto getRecordName() const -> std::string { return enter_name_ ? enter_name_->getFinalName() : "xxx"; }
|
||||
[[nodiscard]] auto getLastEnterName() const -> std::string { return last_enter_name_; }
|
||||
[[nodiscard]] auto getScore() const -> int { return score_; }
|
||||
[[nodiscard]] auto getScoreBoardPanel() const -> int { return scoreboard_panel_; }
|
||||
[[nodiscard]] auto getScoreBoardPanel() const -> Scoreboard::Id { return scoreboard_panel_; }
|
||||
[[nodiscard]] static auto getWidth() -> int { return WIDTH; }
|
||||
[[nodiscard]] auto getPlayingState() const -> PlayerState { return playing_state_; }
|
||||
[[nodiscard]] auto getPlayingState() const -> State { return playing_state_; }
|
||||
[[nodiscard]] auto getName() const -> const std::string & { return name_; }
|
||||
[[nodiscard]] auto get1CC() const -> bool { return game_completed_ && credits_used_ == 1; }
|
||||
[[nodiscard]] auto getEnterNamePositionOverflow() const -> bool { return enter_name_ ? enter_name_->getPositionOverflow() : false; }
|
||||
@@ -149,25 +150,26 @@ class Player {
|
||||
// Setters inline
|
||||
void setController(int index) { controller_index_ = index; }
|
||||
void setCantFireCounter(int counter) { recoiling_state_duration_ = cant_fire_counter_ = counter; }
|
||||
void setFiringState(PlayerState state) { firing_state_ = state; }
|
||||
void setFiringState(State state) { firing_state_ = state; }
|
||||
void setInvulnerableCounter(int value) { invulnerable_counter_ = value; }
|
||||
void setName(const std::string &name) { name_ = name; }
|
||||
void setPowerUpCounter(int value) { power_up_counter_ = value; }
|
||||
void setScore(int score) { score_ = score; }
|
||||
void setScoreBoardPanel(int panel) { scoreboard_panel_ = panel; }
|
||||
void setScoreBoardPanel(Scoreboard::Id panel) { scoreboard_panel_ = panel; }
|
||||
void setScoreMultiplier(float value) { score_multiplier_ = value; }
|
||||
void setWalkingState(PlayerState state) { walking_state_ = state; }
|
||||
void setWalkingState(State state) { walking_state_ = state; }
|
||||
void addCredit() { ++credits_used_; }
|
||||
|
||||
private:
|
||||
// --- Constantes ---
|
||||
static constexpr int POWERUP_COUNTER = 1500; // Duración del estado PowerUp
|
||||
static constexpr int INVULNERABLE_COUNTER = 200; // Duración del estado invulnerable
|
||||
static constexpr int WIDTH = 30; // Anchura
|
||||
static constexpr int HEIGHT = 30; // Altura
|
||||
static constexpr int WIDTH = 32; // Anchura
|
||||
static constexpr int HEIGHT = 32; // Altura
|
||||
static constexpr float BASE_SPEED = 1.5F; // Velocidad base del jugador
|
||||
static constexpr int COOLING_DURATION = 50;
|
||||
static constexpr int COOLING_COMPLETE = 0;
|
||||
static constexpr int WAITING_COUNTER = 1000;
|
||||
|
||||
// --- Objetos y punteros ---
|
||||
std::unique_ptr<AnimatedSprite> player_sprite_; // Sprite para dibujar el jugador
|
||||
@@ -175,81 +177,83 @@ class Player {
|
||||
std::unique_ptr<EnterName> enter_name_; // Clase utilizada para introducir el nombre
|
||||
|
||||
// --- Variables de estado ---
|
||||
int id_; // Número de identificación para el jugador. Player1 = 1, Player2 = 2
|
||||
SDL_FRect play_area_; // Rectángulo con la zona de juego
|
||||
float pos_x_ = 0.0F; // Posición en el eje X
|
||||
int pos_y_ = 0; // Posición en el eje Y
|
||||
float default_pos_x_; // Posición inicial para el jugador
|
||||
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 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
|
||||
PlayerState walking_state_ = PlayerState::WALKING_STOP; // Estado del jugador al moverse
|
||||
PlayerState firing_state_ = PlayerState::FIRING_NONE; // Estado del jugador al disparar
|
||||
PlayerState playing_state_ = PlayerState::WAITING; // Estado del jugador en el juego
|
||||
bool invulnerable_ = true; // Indica si el jugador es invulnerable
|
||||
int invulnerable_counter_ = INVULNERABLE_COUNTER; // Contador para la invulnerabilidad
|
||||
bool extra_hit_ = false; // Indica si el jugador tiene un toque extra
|
||||
int coffees_ = 0; // Indica cuántos cafés lleva acumulados
|
||||
bool power_up_ = false; // Indica si el jugador tiene activo el modo PowerUp
|
||||
int power_up_counter_ = POWERUP_COUNTER; // Temporizador para el modo PowerUp
|
||||
int power_up_x_offset_ = 0; // Desplazamiento del sprite de PowerUp respecto al sprite del jugador
|
||||
Circle collider_ = Circle(0, 0, 9); // Círculo de colisión del jugador
|
||||
int continue_counter_ = 10; // Contador para poder continuar
|
||||
Uint32 continue_ticks_ = 0; // Variable para poder cambiar el contador de continue en función del tiempo
|
||||
int scoreboard_panel_ = 0; // Panel del marcador asociado al jugador
|
||||
std::string name_; // Nombre del jugador
|
||||
int controller_index_ = 0; // Índice del array de mandos que utilizará para moverse
|
||||
bool demo_ = false; // Para que el jugador sepa si está en el modo demostración
|
||||
int name_entry_idle_counter_ = 0; // Contador para poner nombre
|
||||
int name_entry_total_counter_ = 0; // Segundos totales que lleva acumulados poniendo nombre
|
||||
Uint32 name_entry_ticks_ = 0; // Variable para poder cambiar el contador de poner nombre en función del tiempo
|
||||
Uint32 showing_name_ticks_ = 0; // Tiempo en el que se entra al estado SHOWING_NAME
|
||||
int step_counter_ = 0; // Cuenta los pasos para los estados en los que camina automáticamente
|
||||
bool game_completed_ = false; // Indica si ha completado el juego
|
||||
int credits_used_ = 1; // Indica el número de veces que ha continuado
|
||||
std::string last_enter_name_; // Último nombre introducido en la tabla de puntuaciones
|
||||
int id_; // Número de identificación para el jugador. Player1 = 1, Player2 = 2
|
||||
SDL_FRect play_area_; // Rectángulo con la zona de juego
|
||||
float pos_x_ = 0.0F; // Posición en el eje X
|
||||
int pos_y_ = 0; // Posición en el eje Y
|
||||
float default_pos_x_; // Posición inicial para el jugador
|
||||
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 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
|
||||
State walking_state_ = State::WALKING_STOP; // Estado del jugador al moverse
|
||||
State firing_state_ = State::FIRING_NONE; // Estado del jugador al disparar
|
||||
State playing_state_ = State::WAITING; // Estado del jugador en el juego
|
||||
bool invulnerable_ = true; // Indica si el jugador es invulnerable
|
||||
int invulnerable_counter_ = INVULNERABLE_COUNTER; // Contador para la invulnerabilidad
|
||||
bool extra_hit_ = false; // Indica si el jugador tiene un toque extra
|
||||
int coffees_ = 0; // Indica cuántos cafés lleva acumulados
|
||||
bool power_up_ = false; // Indica si el jugador tiene activo el modo PowerUp
|
||||
int power_up_counter_ = POWERUP_COUNTER; // Temporizador para el modo PowerUp
|
||||
int power_up_x_offset_ = 0; // Desplazamiento del sprite de PowerUp respecto al sprite del jugador
|
||||
Circle collider_ = Circle(0, 0, 9); // Círculo de colisión del jugador
|
||||
int continue_counter_ = 10; // Contador para poder continuar
|
||||
Uint32 continue_ticks_ = 0; // Variable para poder cambiar el contador de continue en función del tiempo
|
||||
Scoreboard::Id scoreboard_panel_ = Scoreboard::Id::LEFT; // Panel del marcador asociado al jugador
|
||||
std::string name_; // Nombre del jugador
|
||||
int controller_index_ = 0; // Índice del array de mandos que utilizará para moverse
|
||||
bool demo_ = false; // Para que el jugador sepa si está en el modo demostración
|
||||
int name_entry_idle_counter_ = 0; // Contador para poner nombre
|
||||
int name_entry_total_counter_ = 0; // Segundos totales que lleva acumulados poniendo nombre
|
||||
Uint32 name_entry_ticks_ = 0; // Variable para poder cambiar el contador de poner nombre en función del tiempo
|
||||
Uint32 showing_name_ticks_ = 0; // Tiempo en el que se entra al estado SHOWING_NAME
|
||||
int step_counter_ = 0; // Cuenta los pasos para los estados en los que camina automáticamente
|
||||
bool game_completed_ = false; // Indica si ha completado el juego
|
||||
int credits_used_ = 1; // Indica el número de veces que ha continuado
|
||||
std::string last_enter_name_; // Último nombre introducido en la tabla de puntuaciones
|
||||
int waiting_counter_ = 0; // Contador para el estado de espera
|
||||
|
||||
// --- Métodos internos ---
|
||||
void shiftColliders(); // Actualiza el círculo de colisión a la posición del jugador
|
||||
void shiftSprite(); // Recoloca el sprite
|
||||
void updateInvulnerable(); // Monitoriza el estado de invulnerabilidad
|
||||
void updateContinueCounter(); // Actualiza el contador de continue
|
||||
void updateEnterNameCounter(); // Actualiza el contador de entrar nombre
|
||||
void updateShowingName(); // Actualiza el estado SHOWING_NAME
|
||||
void decNameEntryCounter(); // Decrementa el contador de entrar nombre
|
||||
void updateScoreboard(); // Actualiza el panel del marcador
|
||||
void setScoreboardMode(ScoreboardMode mode) const; // Cambia el modo del marcador
|
||||
void playSound(const std::string &name) const; // Hace sonar un sonido
|
||||
[[nodiscard]] auto isRenderable() const -> bool; // Indica si se puede dibujar el objeto
|
||||
void addScoreToScoreBoard() const; // Añade una puntuación a la tabla de records
|
||||
void handleFiringCooldown(); // Gestiona el tiempo de espera después de disparar antes de permitir otro disparo
|
||||
void handleRecoilAndCooling(); // Procesa simultáneamente el retroceso del arma y la transición al estado de enfriamiento si aplica
|
||||
void handleCoolingState(); // Actualiza la lógica interna mientras el sistema está en estado de enfriamiento
|
||||
void transitionToRecoiling(); // Cambia el estado actual al de retroceso después de disparar
|
||||
void transitionToCooling(); // Cambia el estado actual al de enfriamiento (por ejemplo, tras una ráfaga o sobrecalentamiento)
|
||||
void completeCooling(); // Finaliza el proceso de enfriamiento y restablece el estado listo para disparar
|
||||
void handlePlayingMovement(); // Gestiona el movimiento del personaje u objeto durante el estado de juego activo
|
||||
void handleRollingMovement(); // Actualiza la lógica de movimiento de "rodar" (posiblemente tras impacto o acción especial)
|
||||
void handleRollingBoundaryCollision(); // Detecta y maneja colisiones del objeto rodante con los límites de la pantalla
|
||||
void handleRollingGroundCollision(); // Gestiona la interacción del objeto rodante con el suelo (rebotes, frenado, etc.)
|
||||
void handleRollingStop(); // Detiene el movimiento del objeto rodante cuando se cumplen las condiciones necesarias
|
||||
void handleRollingBounce(); // Aplica una lógica de rebote al colisionar con superficies durante el rodamiento
|
||||
void handleTitleAnimation(); // Ejecuta la animación del título en pantalla (ej. entrada, parpadeo o desplazamiento)
|
||||
void handleContinueTimeOut(); // Gestiona el tiempo de espera en la pantalla de "Continuar" y decide si pasar a otro estado
|
||||
void handleLeavingScreen(); // Lógica para salir de la pantalla actual (transición visual o cambio de escena)
|
||||
void handleEnteringScreen(); // Lógica para entrar en una nueva pantalla, posiblemente con animación o retraso
|
||||
void handlePlayer1Entering(); // Controla la animación o posición de entrada del Jugador 1 en pantalla
|
||||
void handlePlayer2Entering(); // Controla la animación o posición de entrada del Jugador 2 en pantalla
|
||||
void handleCreditsMovement(); // Movimiento general en la pantalla de créditos (desplazamiento vertical u horizontal)
|
||||
void handleCreditsRightMovement(); // Lógica específica para mover los créditos hacia la derecha
|
||||
void handleCreditsLeftMovement(); // Lógica específica para mover los créditos hacia la izquierda
|
||||
void updateWalkingStateForCredits(); // Actualiza el estado de caminata de algún personaje u elemento animado en los créditos
|
||||
void setInputBasedOnPlayerId(); // Asocia las entradas de control en función del identificador del jugador (teclas, mando, etc.)
|
||||
void updateStepCounter(); // Incrementa o ajusta el contador de pasos para animaciones o mecánicas relacionadas con movimiento
|
||||
void shiftColliders(); // Actualiza el círculo de colisión a la posición del jugador
|
||||
void shiftSprite(); // Recoloca el sprite
|
||||
void updateInvulnerable(); // Monitoriza el estado de invulnerabilidad
|
||||
void updateContinueCounter(); // Actualiza el contador de continue
|
||||
void updateEnterNameCounter(); // Actualiza el contador de entrar nombre
|
||||
void updateShowingName(); // Actualiza el estado SHOWING_NAME
|
||||
void decNameEntryCounter(); // Decrementa el contador de entrar nombre
|
||||
void updateScoreboard(); // Actualiza el panel del marcador
|
||||
void setScoreboardMode(Scoreboard::Mode mode) const; // Cambia el modo del marcador
|
||||
void playSound(const std::string &name) const; // Hace sonar un sonido
|
||||
[[nodiscard]] auto isRenderable() const -> bool; // Indica si se puede dibujar el objeto
|
||||
void addScoreToScoreBoard() const; // Añade una puntuación a la tabla de records
|
||||
void handleFiringCooldown(); // Gestiona el tiempo de espera después de disparar antes de permitir otro disparo
|
||||
void handleRecoilAndCooling(); // Procesa simultáneamente el retroceso del arma y la transición al estado de enfriamiento si aplica
|
||||
void handleCoolingState(); // Actualiza la lógica interna mientras el sistema está en estado de enfriamiento
|
||||
void transitionToRecoiling(); // Cambia el estado actual al de retroceso después de disparar
|
||||
void transitionToCooling(); // Cambia el estado actual al de enfriamiento (por ejemplo, tras una ráfaga o sobrecalentamiento)
|
||||
void completeCooling(); // Finaliza el proceso de enfriamiento y restablece el estado listo para disparar
|
||||
void handlePlayingMovement(); // Gestiona el movimiento del personaje u objeto durante el estado de juego activo
|
||||
void handleRollingMovement(); // Actualiza la lógica de movimiento de "rodar" (posiblemente tras impacto o acción especial)
|
||||
void handleRollingBoundaryCollision(); // Detecta y maneja colisiones del objeto rodante con los límites de la pantalla
|
||||
void handleRollingGroundCollision(); // Gestiona la interacción del objeto rodante con el suelo (rebotes, frenado, etc.)
|
||||
void handleRollingStop(); // Detiene el movimiento del objeto rodante cuando se cumplen las condiciones necesarias
|
||||
void handleRollingBounce(); // Aplica una lógica de rebote al colisionar con superficies durante el rodamiento
|
||||
void handleTitleAnimation(); // Ejecuta la animación del título en pantalla (ej. entrada, parpadeo o desplazamiento)
|
||||
void handleContinueTimeOut(); // Gestiona el tiempo de espera en la pantalla de "Continuar" y decide si pasar a otro estado
|
||||
void handleLeavingScreen(); // Lógica para salir de la pantalla actual (transición visual o cambio de escena)
|
||||
void handleEnteringScreen(); // Lógica para entrar en una nueva pantalla, posiblemente con animación o retraso
|
||||
void handlePlayer1Entering(); // Controla la animación o posición de entrada del Jugador 1 en pantalla
|
||||
void handlePlayer2Entering(); // Controla la animación o posición de entrada del Jugador 2 en pantalla
|
||||
void handleCreditsMovement(); // Movimiento general en la pantalla de créditos (desplazamiento vertical u horizontal)
|
||||
void handleCreditsRightMovement(); // Lógica específica para mover los créditos hacia la derecha
|
||||
void handleCreditsLeftMovement(); // Lógica específica para mover los créditos hacia la izquierda
|
||||
void handleWaitingMovement(); // Controla la animación del jugador saludando
|
||||
void updateWalkingStateForCredits(); // Actualiza el estado de caminata de algún personaje u elemento animado en los créditos
|
||||
void setInputBasedOnPlayerId(); // Asocia las entradas de control en función del identificador del jugador (teclas, mando, etc.)
|
||||
void updateStepCounter(); // Incrementa o ajusta el contador de pasos para animaciones o mecánicas relacionadas con movimiento
|
||||
};
|
||||
@@ -17,20 +17,20 @@
|
||||
#include "text.h" // Para Text, TEXT_CENTER, TEXT_COLOR
|
||||
#include "texture.h" // Para Texture
|
||||
|
||||
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
|
||||
// .at(SINGLETON) Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
|
||||
Scoreboard *Scoreboard::instance = nullptr;
|
||||
|
||||
// [SINGLETON] Crearemos el objeto score_board con esta función estática
|
||||
// .at(SINGLETON) Crearemos el objeto score_board con esta función estática
|
||||
void Scoreboard::init() {
|
||||
Scoreboard::instance = new Scoreboard();
|
||||
}
|
||||
|
||||
// [SINGLETON] Destruiremos el objeto score_board con esta función estática
|
||||
// .at(SINGLETON) Destruiremos el objeto score_board con esta función estática
|
||||
void Scoreboard::destroy() {
|
||||
delete Scoreboard::instance;
|
||||
}
|
||||
|
||||
// [SINGLETON] Con este método obtenemos el objeto score_board y podemos trabajar con él
|
||||
// .at(SINGLETON) Con este método obtenemos el objeto score_board y podemos trabajar con él
|
||||
auto Scoreboard::get() -> Scoreboard * {
|
||||
return Scoreboard::instance;
|
||||
}
|
||||
@@ -42,18 +42,18 @@ Scoreboard::Scoreboard()
|
||||
power_meter_sprite_(std::make_unique<Sprite>(game_power_meter_texture_)),
|
||||
text_scoreboard_(Resource::get()->getText("8bithud")) {
|
||||
// Inicializa variables
|
||||
for (int i = 0; i < SCOREBOARD_MAX_PANELS; ++i) {
|
||||
name_[i].clear();
|
||||
record_name_[i].clear();
|
||||
selector_pos_[i] = 0;
|
||||
score_[i] = 0;
|
||||
mult_[i] = 0;
|
||||
continue_counter_[i] = 0;
|
||||
for (size_t i = 0; i < static_cast<size_t>(Id::SIZE); ++i) {
|
||||
name_.at(i).clear();
|
||||
record_name_.at(i).clear();
|
||||
selector_pos_.at(i) = 0;
|
||||
score_.at(i) = 0;
|
||||
mult_.at(i) = 0;
|
||||
continue_counter_.at(i) = 0;
|
||||
}
|
||||
|
||||
panel_[SCOREBOARD_LEFT_PANEL].mode = ScoreboardMode::SCORE;
|
||||
panel_[SCOREBOARD_RIGHT_PANEL].mode = ScoreboardMode::SCORE;
|
||||
panel_[SCOREBOARD_CENTER_PANEL].mode = ScoreboardMode::STAGE_INFO;
|
||||
panel_.at(static_cast<size_t>(Id::LEFT)).mode = Mode::SCORE;
|
||||
panel_.at(static_cast<size_t>(Id::RIGHT)).mode = Mode::SCORE;
|
||||
panel_.at(static_cast<size_t>(Id::CENTER)).mode = Mode::STAGE_INFO;
|
||||
|
||||
// Recalcula las anclas de los elementos
|
||||
recalculateAnchors();
|
||||
@@ -147,9 +147,9 @@ void Scoreboard::fillPanelTextures() {
|
||||
auto *temp = SDL_GetRenderTarget(renderer_);
|
||||
|
||||
// Genera el contenido de cada panel_
|
||||
for (size_t i = 0; i < SCOREBOARD_MAX_PANELS; ++i) {
|
||||
for (size_t i = 0; i < static_cast<int>(Id::SIZE); ++i) {
|
||||
// Cambia el destino del renderizador
|
||||
SDL_SetRenderTarget(renderer_, panel_texture_[i]);
|
||||
SDL_SetRenderTarget(renderer_, panel_texture_.at(i));
|
||||
|
||||
// Dibuja el fondo de la textura
|
||||
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
|
||||
@@ -163,32 +163,32 @@ void Scoreboard::fillPanelTextures() {
|
||||
}
|
||||
|
||||
void Scoreboard::renderPanelContent(size_t panel_index) {
|
||||
switch (panel_[panel_index].mode) {
|
||||
case ScoreboardMode::SCORE:
|
||||
switch (panel_.at(panel_index).mode) {
|
||||
case Mode::SCORE:
|
||||
renderScoreMode(panel_index);
|
||||
break;
|
||||
case ScoreboardMode::DEMO:
|
||||
case Mode::DEMO:
|
||||
renderDemoMode();
|
||||
break;
|
||||
case ScoreboardMode::WAITING:
|
||||
case Mode::WAITING:
|
||||
renderWaitingMode();
|
||||
break;
|
||||
case ScoreboardMode::GAME_OVER:
|
||||
case Mode::GAME_OVER:
|
||||
renderGameOverMode();
|
||||
break;
|
||||
case ScoreboardMode::STAGE_INFO:
|
||||
case Mode::STAGE_INFO:
|
||||
renderStageInfoMode();
|
||||
break;
|
||||
case ScoreboardMode::CONTINUE:
|
||||
case Mode::CONTINUE:
|
||||
renderContinueMode(panel_index);
|
||||
break;
|
||||
case ScoreboardMode::ENTER_NAME:
|
||||
case Mode::ENTER_NAME:
|
||||
renderEnterNameMode(panel_index);
|
||||
break;
|
||||
case ScoreboardMode::SHOW_NAME:
|
||||
case Mode::SHOW_NAME:
|
||||
renderShowNameMode(panel_index);
|
||||
break;
|
||||
case ScoreboardMode::GAME_COMPLETED:
|
||||
case Mode::GAME_COMPLETED:
|
||||
renderGameCompletedMode(panel_index);
|
||||
break;
|
||||
default:
|
||||
@@ -198,12 +198,12 @@ void Scoreboard::renderPanelContent(size_t panel_index) {
|
||||
|
||||
void Scoreboard::renderScoreMode(size_t panel_index) {
|
||||
// SCORE
|
||||
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_1_.x, slot4_1_.y, name_[panel_index], 1, text_color1_);
|
||||
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_2_.x, slot4_2_.y, updateScoreText(score_[panel_index]), 1, text_color2_);
|
||||
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_1_.x, slot4_1_.y, name_.at(panel_index), 1, text_color1_);
|
||||
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_2_.x, slot4_2_.y, updateScoreText(score_.at(panel_index)), 1, text_color2_);
|
||||
|
||||
// MULT
|
||||
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 3"), 1, text_color1_);
|
||||
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_4_.x, slot4_4_.y, "x" + std::to_string(mult_[panel_index]).substr(0, 3), 1, text_color2_);
|
||||
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_4_.x, slot4_4_.y, "x" + std::to_string(mult_.at(panel_index)).substr(0, 3), 1, text_color2_);
|
||||
}
|
||||
|
||||
void Scoreboard::renderDemoMode() {
|
||||
@@ -257,18 +257,18 @@ void Scoreboard::renderStageInfoMode() {
|
||||
|
||||
void Scoreboard::renderContinueMode(size_t panel_index) {
|
||||
// SCORE
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, name_[panel_index], 1, text_color1_);
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_[panel_index]), 1, text_color2_);
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, name_.at(panel_index), 1, text_color1_);
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_.at(panel_index)), 1, text_color2_);
|
||||
|
||||
// CONTINUE
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 10"), 1, text_color1_);
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y, std::to_string(continue_counter_[panel_index]), 1, text_color2_);
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y, std::to_string(continue_counter_.at(panel_index)), 1, text_color2_);
|
||||
}
|
||||
|
||||
void Scoreboard::renderEnterNameMode(size_t panel_index) {
|
||||
// SCORE
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, name_[panel_index], 1, text_color1_);
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_[panel_index]), 1, text_color2_);
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, name_.at(panel_index), 1, text_color1_);
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_.at(panel_index)), 1, text_color2_);
|
||||
|
||||
// ENTER NAME
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
|
||||
@@ -282,18 +282,18 @@ void Scoreboard::renderNameInputField(size_t panel_index) {
|
||||
// Recorre todos los slots de letras del nombre
|
||||
for (size_t j = 0; j < NAME_SIZE; ++j) {
|
||||
// Selecciona el color
|
||||
const Color COLOR = j < selector_pos_[panel_index] ? text_color2_ : text_color1_;
|
||||
const Color COLOR = j < selector_pos_.at(panel_index) ? text_color2_ : text_color1_;
|
||||
|
||||
if (j != selector_pos_[panel_index] || time_counter_ % 3 == 0) {
|
||||
if (j != selector_pos_.at(panel_index) || time_counter_ % 3 == 0) {
|
||||
// Dibuja la linea
|
||||
if (j >= selector_pos_[panel_index]) {
|
||||
if (j >= selector_pos_.at(panel_index)) {
|
||||
SDL_SetRenderDrawColor(renderer_, COLOR.r, COLOR.g, COLOR.b, 255);
|
||||
SDL_RenderLine(renderer_, rect.x, rect.y + rect.h, rect.x + rect.w, rect.y + rect.h);
|
||||
}
|
||||
|
||||
// Dibuja la letra
|
||||
if (j < record_name_[panel_index].size()) {
|
||||
text_scoreboard_->writeColored(rect.x, rect.y, record_name_[panel_index].substr(j, 1), COLOR);
|
||||
if (j < record_name_.at(panel_index).size()) {
|
||||
text_scoreboard_->writeColored(rect.x, rect.y, record_name_.at(panel_index).substr(j, 1), COLOR);
|
||||
}
|
||||
}
|
||||
rect.x += 7;
|
||||
@@ -302,17 +302,17 @@ void Scoreboard::renderNameInputField(size_t panel_index) {
|
||||
|
||||
void Scoreboard::renderShowNameMode(size_t panel_index) {
|
||||
// SCORE
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, name_[panel_index], 1, text_color1_);
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_[panel_index]), 1, text_color2_);
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, name_.at(panel_index), 1, text_color1_);
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_.at(panel_index)), 1, text_color2_);
|
||||
|
||||
// NAME
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
|
||||
|
||||
/* TEXTO CENTRADO */
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y, record_name_[panel_index], 1, getColorLikeKnightRider(name_colors_, loop_counter_ / 5));
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y, record_name_.at(panel_index), 1, getColorLikeKnightRider(name_colors_, loop_counter_ / 5));
|
||||
|
||||
/* TEXTO A LA IZQUIERDA */
|
||||
// text_scoreboard_->writeColored(enter_name_pos_.x, enter_name_pos_.y, record_name_[panelIndex], getColorLikeKnightRider(name_colors_, loop_counter_ / 5));
|
||||
// text_scoreboard_->writeColored(enter_name_pos_.x, enter_name_pos_.y, record_name_.at(panelIndex), getColorLikeKnightRider(name_colors_, loop_counter_ / 5));
|
||||
}
|
||||
|
||||
void Scoreboard::renderGameCompletedMode(size_t panel_index) {
|
||||
@@ -322,7 +322,7 @@ void Scoreboard::renderGameCompletedMode(size_t panel_index) {
|
||||
// SCORE
|
||||
if (time_counter_ % 10 < 8) {
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 14"), 1, text_color1_);
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y - 2, updateScoreText(score_[panel_index]), 1, text_color2_);
|
||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y - 2, updateScoreText(score_.at(panel_index)), 1, text_color2_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,8 +340,8 @@ void Scoreboard::fillBackgroundTexture() {
|
||||
SDL_RenderClear(renderer_);
|
||||
|
||||
// Copia las texturas de los paneles
|
||||
for (int i = 0; i < SCOREBOARD_MAX_PANELS; ++i) {
|
||||
SDL_RenderTexture(renderer_, panel_texture_[i], nullptr, &panel_[i].pos);
|
||||
for (int i = 0; i < static_cast<int>(Id::SIZE); ++i) {
|
||||
SDL_RenderTexture(renderer_, panel_texture_.at(i), nullptr, &panel_.at(i).pos);
|
||||
}
|
||||
|
||||
// Dibuja la linea que separa la zona de juego del marcador
|
||||
@@ -354,12 +354,12 @@ void Scoreboard::fillBackgroundTexture() {
|
||||
// Recalcula las anclas de los elementos
|
||||
void Scoreboard::recalculateAnchors() {
|
||||
// Recalcula la posición y el tamaño de los paneles
|
||||
const float PANEL_WIDTH = rect_.w / (float)SCOREBOARD_MAX_PANELS;
|
||||
for (int i = 0; i < SCOREBOARD_MAX_PANELS; ++i) {
|
||||
panel_[i].pos.x = roundf(PANEL_WIDTH * i);
|
||||
panel_[i].pos.y = 0;
|
||||
panel_[i].pos.w = roundf(PANEL_WIDTH * (i + 1)) - panel_[i].pos.x;
|
||||
panel_[i].pos.h = rect_.h;
|
||||
const float PANEL_WIDTH = rect_.w / (float)static_cast<int>(Id::SIZE);
|
||||
for (int i = 0; i < static_cast<int>(Id::SIZE); ++i) {
|
||||
panel_.at(i).pos.x = roundf(PANEL_WIDTH * i);
|
||||
panel_.at(i).pos.y = 0;
|
||||
panel_.at(i).pos.w = roundf(PANEL_WIDTH * (i + 1)) - panel_.at(i).pos.x;
|
||||
panel_.at(i).pos.h = rect_.h;
|
||||
}
|
||||
|
||||
// Constantes para definir las zonas del panel_: 4 filas y 1 columna
|
||||
|
||||
@@ -14,35 +14,36 @@ class Sprite;
|
||||
class Text;
|
||||
class Texture;
|
||||
|
||||
// --- Defines ---
|
||||
constexpr int SCOREBOARD_LEFT_PANEL = 0;
|
||||
constexpr int SCOREBOARD_CENTER_PANEL = 1;
|
||||
constexpr int SCOREBOARD_RIGHT_PANEL = 2;
|
||||
constexpr int SCOREBOARD_MAX_PANELS = 3;
|
||||
|
||||
// --- Enums ---
|
||||
enum class ScoreboardMode : int {
|
||||
SCORE,
|
||||
STAGE_INFO,
|
||||
CONTINUE,
|
||||
WAITING,
|
||||
GAME_OVER,
|
||||
DEMO,
|
||||
ENTER_NAME,
|
||||
SHOW_NAME,
|
||||
GAME_COMPLETED,
|
||||
NUM_MODES,
|
||||
};
|
||||
|
||||
// --- Structs ---
|
||||
struct Panel {
|
||||
ScoreboardMode mode; // Modo en el que se encuentra el panel
|
||||
SDL_FRect pos; // Posición donde dibujar el panel dentro del marcador
|
||||
};
|
||||
|
||||
// --- Clase Scoreboard ---
|
||||
class Scoreboard {
|
||||
public:
|
||||
// --- Enums ---
|
||||
enum class Id : size_t {
|
||||
LEFT = 0,
|
||||
CENTER = 1,
|
||||
RIGHT = 2,
|
||||
SIZE = 3
|
||||
};
|
||||
|
||||
enum class Mode : int {
|
||||
SCORE,
|
||||
STAGE_INFO,
|
||||
CONTINUE,
|
||||
WAITING,
|
||||
GAME_OVER,
|
||||
DEMO,
|
||||
ENTER_NAME,
|
||||
SHOW_NAME,
|
||||
GAME_COMPLETED,
|
||||
NUM_MODES,
|
||||
};
|
||||
|
||||
// --- Structs ---
|
||||
struct Panel {
|
||||
Mode mode; // Modo en el que se encuentra el panel
|
||||
SDL_FRect pos; // Posición donde dibujar el panel dentro del marcador
|
||||
};
|
||||
|
||||
// --- Métodos de singleton ---
|
||||
static void init(); // Crea el objeto Scoreboard
|
||||
static void destroy(); // Libera el objeto Scoreboard
|
||||
@@ -55,16 +56,16 @@ class Scoreboard {
|
||||
// --- Setters ---
|
||||
void setColor(Color color); // Establece el color del marcador
|
||||
void setPos(SDL_FRect rect); // Establece la posición y tamaño del marcador
|
||||
void setContinue(int panel, int continue_counter) { continue_counter_[panel] = continue_counter; }
|
||||
void setContinue(Id id, int continue_counter) { continue_counter_.at(static_cast<size_t>(id)) = continue_counter; }
|
||||
void setHiScore(int hi_score) { hi_score_ = hi_score; }
|
||||
void setHiScoreName(const std::string &name) { hi_score_name_ = name; }
|
||||
void setMode(int index, ScoreboardMode mode) { panel_[index].mode = mode; }
|
||||
void setMult(int panel, float mult) { mult_[panel] = mult; }
|
||||
void setName(int panel, const std::string &name) { name_[panel] = name; }
|
||||
void setMode(Id id, Mode mode) { panel_.at(static_cast<size_t>(id)).mode = mode; }
|
||||
void setMult(Id id, float mult) { mult_.at(static_cast<size_t>(id)) = mult; }
|
||||
void setName(Id id, const std::string &name) { name_.at(static_cast<size_t>(id)) = name; }
|
||||
void setPower(float power) { power_ = power; }
|
||||
void setRecordName(int panel, const std::string &record_name) { record_name_[panel] = record_name; }
|
||||
void setScore(int panel, int score) { score_[panel] = score; }
|
||||
void setSelectorPos(int panel, int pos) { selector_pos_[panel] = pos; }
|
||||
void setRecordName(Id id, const std::string &record_name) { record_name_.at(static_cast<size_t>(id)) = record_name; }
|
||||
void setScore(Id id, int score) { score_.at(static_cast<size_t>(id)) = score; }
|
||||
void setSelectorPos(Id id, int pos) { selector_pos_.at(static_cast<size_t>(id)) = pos; }
|
||||
void setStage(int stage) { stage_ = stage; }
|
||||
|
||||
private:
|
||||
@@ -77,13 +78,13 @@ class Scoreboard {
|
||||
std::vector<SDL_Texture *> panel_texture_; // Texturas para dibujar cada panel
|
||||
|
||||
// --- Variables de estado ---
|
||||
std::array<std::string, SCOREBOARD_MAX_PANELS> name_ = {}; // Nombre de cada jugador
|
||||
std::array<std::string, SCOREBOARD_MAX_PANELS> record_name_ = {}; // Nombre introducido para la tabla de records
|
||||
std::array<size_t, SCOREBOARD_MAX_PANELS> selector_pos_ = {}; // Posición del selector de letra para introducir el nombre
|
||||
std::array<int, SCOREBOARD_MAX_PANELS> score_ = {}; // Puntuación de los jugadores
|
||||
std::array<float, SCOREBOARD_MAX_PANELS> mult_ = {}; // Multiplicador de los jugadores
|
||||
std::array<int, SCOREBOARD_MAX_PANELS> continue_counter_ = {}; // Tiempo para continuar de los jugadores
|
||||
std::array<Panel, SCOREBOARD_MAX_PANELS> panel_ = {}; // Lista con todos los paneles del marcador
|
||||
std::array<std::string, static_cast<int>(Id::SIZE)> name_ = {}; // Nombre de cada jugador
|
||||
std::array<std::string, static_cast<int>(Id::SIZE)> record_name_ = {}; // Nombre introducido para la tabla de records
|
||||
std::array<size_t, static_cast<int>(Id::SIZE)> selector_pos_ = {}; // Posición del selector de letra para introducir el nombre
|
||||
std::array<int, static_cast<int>(Id::SIZE)> score_ = {}; // Puntuación de los jugadores
|
||||
std::array<float, static_cast<int>(Id::SIZE)> mult_ = {}; // Multiplicador de los jugadores
|
||||
std::array<int, static_cast<int>(Id::SIZE)> continue_counter_ = {}; // Tiempo para continuar de los jugadores
|
||||
std::array<Panel, static_cast<int>(Id::SIZE)> panel_ = {}; // Lista con todos los paneles del marcador
|
||||
|
||||
int stage_ = 1; // Número de fase actual
|
||||
int hi_score_ = 0; // Máxima puntuación
|
||||
|
||||
@@ -354,12 +354,12 @@ void Credits::initPlayers() {
|
||||
constexpr bool DEMO = false;
|
||||
constexpr int AWAY_DISTANCE = 700;
|
||||
players_.emplace_back(std::make_unique<Player>(1, play_area_.x - AWAY_DISTANCE - PLAYER_WIDTH, Y, DEMO, play_area_, player_textures.at(0), player_animations));
|
||||
players_.back()->setWalkingState(PlayerState::WALKING_RIGHT);
|
||||
players_.back()->setPlayingState(PlayerState::CREDITS);
|
||||
players_.back()->setWalkingState(Player::State::WALKING_RIGHT);
|
||||
players_.back()->setPlayingState(Player::State::CREDITS);
|
||||
|
||||
players_.emplace_back(std::make_unique<Player>(2, play_area_.x + play_area_.w + AWAY_DISTANCE, Y, DEMO, play_area_, player_textures.at(1), player_animations));
|
||||
players_.back()->setWalkingState(PlayerState::WALKING_LEFT);
|
||||
players_.back()->setPlayingState(PlayerState::CREDITS);
|
||||
players_.back()->setWalkingState(Player::State::WALKING_LEFT);
|
||||
players_.back()->setPlayingState(Player::State::CREDITS);
|
||||
}
|
||||
|
||||
// Actualiza los rectangulos negros
|
||||
|
||||
@@ -237,9 +237,7 @@ void Game::updatePlayers() {
|
||||
// Dibuja a los jugadores
|
||||
void Game::renderPlayers() {
|
||||
for (auto &player : players_) {
|
||||
if (!player->isWaiting()) {
|
||||
player->render();
|
||||
}
|
||||
player->render();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,9 +361,9 @@ void Game::updateGameStateCompleted() {
|
||||
for (auto &player : players_) {
|
||||
if (player->isPlaying()) {
|
||||
player->addScore(1000000);
|
||||
player->setPlayingState(PlayerState::CELEBRATING);
|
||||
player->setPlayingState(Player::State::CELEBRATING);
|
||||
} else {
|
||||
player->setPlayingState(PlayerState::GAME_OVER);
|
||||
player->setPlayingState(Player::State::GAME_OVER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,14 +374,14 @@ void Game::updateGameStateCompleted() {
|
||||
if (game_completed_counter_ == END_CELEBRATIONS) {
|
||||
for (auto &player : players_) {
|
||||
if (player->isCelebrating()) {
|
||||
player->setPlayingState(player->isEligibleForHighScore() ? PlayerState::ENTERING_NAME_GAME_COMPLETED : PlayerState::LEAVING_SCREEN);
|
||||
player->setPlayingState(player->isEligibleForHighScore() ? Player::State::ENTERING_NAME_GAME_COMPLETED : Player::State::LEAVING_SCREEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Si los jugadores ya no estan y no quedan mensajes en pantalla
|
||||
if (allPlayersAreGameOver() && path_sprites_.empty()) {
|
||||
setState(GameState::GAME_OVER);
|
||||
setState(State::GAME_OVER);
|
||||
}
|
||||
|
||||
// Incrementa el contador al final
|
||||
@@ -392,12 +390,12 @@ void Game::updateGameStateCompleted() {
|
||||
|
||||
// Comprueba el estado del juego
|
||||
void Game::checkState() {
|
||||
if (state_ != GameState::COMPLETED && Stage::number == 10) {
|
||||
setState(GameState::COMPLETED);
|
||||
if (state_ != State::COMPLETED && Stage::number == 10) {
|
||||
setState(State::COMPLETED);
|
||||
}
|
||||
|
||||
if (state_ != GameState::GAME_OVER && allPlayersAreGameOver()) {
|
||||
setState(GameState::GAME_OVER);
|
||||
if (state_ != State::GAME_OVER && allPlayersAreGameOver()) {
|
||||
setState(State::GAME_OVER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,7 +523,7 @@ auto Game::checkBulletTabeCollision(std::shared_ptr<Bullet> bullet) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
tabe_->setState(TabeState::HIT);
|
||||
tabe_->setState(Tabe::State::HIT);
|
||||
bullet->disable();
|
||||
|
||||
handleTabeHitEffects();
|
||||
@@ -859,7 +857,7 @@ void Game::handlePlayerCollision(std::shared_ptr<Player> &player, std::shared_pt
|
||||
}
|
||||
screen_->shake();
|
||||
playSound("voice_no.wav");
|
||||
player->setPlayingState(PlayerState::ROLLING);
|
||||
player->setPlayingState(Player::State::ROLLING);
|
||||
players_to_reorder_.push_back(player);
|
||||
if (allPlayersAreNotPlaying()) {
|
||||
Stage::power_can_be_added = false; // No se puede subir poder de fase si no hay nadie jugando
|
||||
@@ -924,22 +922,22 @@ void Game::render() {
|
||||
void Game::updateGameStates() {
|
||||
if (!paused_) {
|
||||
switch (state_) {
|
||||
case GameState::FADE_IN:
|
||||
case State::FADE_IN:
|
||||
updateGameStateFadeIn();
|
||||
break;
|
||||
case GameState::ENTERING_PLAYER:
|
||||
case State::ENTERING_PLAYER:
|
||||
updateGameStateEnteringPlayer();
|
||||
break;
|
||||
case GameState::SHOWING_GET_READY_MESSAGE:
|
||||
case State::SHOWING_GET_READY_MESSAGE:
|
||||
updateGameStateShowingGetReadyMessage();
|
||||
break;
|
||||
case GameState::PLAYING:
|
||||
case State::PLAYING:
|
||||
updateGameStatePlaying();
|
||||
break;
|
||||
case GameState::COMPLETED:
|
||||
case State::COMPLETED:
|
||||
updateGameStateCompleted();
|
||||
break;
|
||||
case GameState::GAME_OVER:
|
||||
case State::GAME_OVER:
|
||||
updateGameStateGameOver();
|
||||
break;
|
||||
default:
|
||||
@@ -951,7 +949,7 @@ void Game::updateGameStates() {
|
||||
// Actualiza el fondo
|
||||
void Game::updateBackground() {
|
||||
// Si el juego está completado, se reduce la velocidad de las nubes
|
||||
if (state_ == GameState::COMPLETED) {
|
||||
if (state_ == State::COMPLETED) {
|
||||
Stage::total_power = (Stage::total_power > 200) ? (Stage::total_power - 25) : 200;
|
||||
}
|
||||
|
||||
@@ -1184,7 +1182,7 @@ void Game::addScoreToScoreBoard(const std::shared_ptr<Player> &player) {
|
||||
// Saca del estado de GAME OVER al jugador si el otro está activo
|
||||
void Game::checkAndUpdatePlayerStatus(int active_player_index, int inactive_player_index) {
|
||||
if (players_[active_player_index]->isGameOver() && !players_[inactive_player_index]->isGameOver() && !players_[inactive_player_index]->isWaiting()) {
|
||||
players_[active_player_index]->setPlayingState(PlayerState::WAITING);
|
||||
players_[active_player_index]->setPlayingState(Player::State::WAITING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1198,7 +1196,7 @@ void Game::checkPlayersStatusPlaying() {
|
||||
if (allPlayersAreWaitingOrGameOver()) {
|
||||
// Entonces los pone en estado de Game Over
|
||||
for (auto &player : players_) {
|
||||
player->setPlayingState(PlayerState::GAME_OVER);
|
||||
player->setPlayingState(Player::State::GAME_OVER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1415,7 +1413,11 @@ void Game::handleFireInputs(const std::shared_ptr<Player> &player, bool autofire
|
||||
void Game::handlePlayerContinue(const std::shared_ptr<Player> &player) {
|
||||
const auto CONTROLLER_INDEX = player->getController();
|
||||
if (input_->checkInput(InputAction::START, INPUT_DO_NOT_ALLOW_REPEAT, Options::controllers[CONTROLLER_INDEX].type, Options::controllers[CONTROLLER_INDEX].index)) {
|
||||
player->setPlayingState(PlayerState::RESPAWNING);
|
||||
if (player->isContinue()) {
|
||||
player->setPlayingState(Player::State::RESPAWNING);
|
||||
} else if (player->isWaiting()) {
|
||||
player->setPlayingState(Player::State::ENTERING_SCREEN);
|
||||
}
|
||||
}
|
||||
|
||||
// Disminuye el contador de continuación si se presiona cualquier botón de disparo.
|
||||
@@ -1433,18 +1435,18 @@ void Game::handleNameInput(const std::shared_ptr<Player> &player) {
|
||||
const auto CONTROLLER_INDEX = player->getController();
|
||||
if (input_->checkInput(InputAction::FIRE_LEFT, INPUT_DO_NOT_ALLOW_REPEAT, Options::controllers[CONTROLLER_INDEX].type, Options::controllers[CONTROLLER_INDEX].index)) {
|
||||
if (player->isShowingName()) {
|
||||
player->setPlayingState(PlayerState::CONTINUE);
|
||||
player->setPlayingState(Player::State::CONTINUE);
|
||||
} else if (player->getEnterNamePositionOverflow()) {
|
||||
player->setInput(InputAction::START);
|
||||
addScoreToScoreBoard(player);
|
||||
player->setPlayingState(PlayerState::SHOWING_NAME);
|
||||
player->setPlayingState(Player::State::SHOWING_NAME);
|
||||
} else {
|
||||
player->setInput(InputAction::RIGHT);
|
||||
}
|
||||
} else if (input_->checkInput(InputAction::FIRE_CENTER, INPUT_DO_NOT_ALLOW_REPEAT, Options::controllers[CONTROLLER_INDEX].type, Options::controllers[CONTROLLER_INDEX].index) ||
|
||||
input_->checkInput(InputAction::FIRE_RIGHT, INPUT_DO_NOT_ALLOW_REPEAT, Options::controllers[CONTROLLER_INDEX].type, Options::controllers[CONTROLLER_INDEX].index)) {
|
||||
if (player->isShowingName()) {
|
||||
player->setPlayingState(PlayerState::CONTINUE);
|
||||
player->setPlayingState(Player::State::CONTINUE);
|
||||
} else {
|
||||
player->setInput(InputAction::LEFT);
|
||||
}
|
||||
@@ -1454,11 +1456,11 @@ void Game::handleNameInput(const std::shared_ptr<Player> &player) {
|
||||
player->setInput(InputAction::DOWN);
|
||||
} else if (input_->checkInput(InputAction::START, INPUT_DO_NOT_ALLOW_REPEAT, Options::controllers[CONTROLLER_INDEX].type, Options::controllers[CONTROLLER_INDEX].index)) {
|
||||
if (player->isShowingName()) {
|
||||
player->setPlayingState(PlayerState::CONTINUE);
|
||||
player->setPlayingState(Player::State::CONTINUE);
|
||||
} else {
|
||||
player->setInput(InputAction::START);
|
||||
addScoreToScoreBoard(player);
|
||||
player->setPlayingState(PlayerState::SHOWING_NAME);
|
||||
player->setPlayingState(Player::State::SHOWING_NAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1467,7 +1469,7 @@ void Game::handleNameInput(const std::shared_ptr<Player> &player) {
|
||||
void Game::initDemo(int player_id) {
|
||||
if (demo_.enabled) {
|
||||
// Cambia el estado del juego
|
||||
setState(GameState::PLAYING);
|
||||
setState(State::PLAYING);
|
||||
|
||||
// Aleatoriza la asignación del fichero con los datos del modo demostracion
|
||||
{
|
||||
@@ -1494,7 +1496,7 @@ void Game::initDemo(int player_id) {
|
||||
if (rand() % 3 != 0) {
|
||||
const auto OTHER_PLAYER_ID = player_id == 1 ? 2 : 1;
|
||||
auto other_player = getPlayer(OTHER_PLAYER_ID);
|
||||
other_player->setPlayingState(PlayerState::PLAYING);
|
||||
other_player->setPlayingState(Player::State::PLAYING);
|
||||
}
|
||||
|
||||
// Asigna cafes a los jugadores
|
||||
@@ -1507,8 +1509,8 @@ void Game::initDemo(int player_id) {
|
||||
}
|
||||
|
||||
// Configura los marcadores
|
||||
scoreboard_->setMode(SCOREBOARD_LEFT_PANEL, ScoreboardMode::DEMO);
|
||||
scoreboard_->setMode(SCOREBOARD_RIGHT_PANEL, ScoreboardMode::DEMO);
|
||||
scoreboard_->setMode(Scoreboard::Id::LEFT, Scoreboard::Mode::DEMO);
|
||||
scoreboard_->setMode(Scoreboard::Id::RIGHT, Scoreboard::Mode::DEMO);
|
||||
|
||||
// Silencia los globos
|
||||
balloon_manager_->setSounds(false);
|
||||
@@ -1534,11 +1536,11 @@ void Game::setTotalPower() {
|
||||
// Inicializa el marcador
|
||||
void Game::initScoreboard() {
|
||||
scoreboard_->setPos(param.scoreboard.rect);
|
||||
scoreboard_->setMode(SCOREBOARD_CENTER_PANEL, ScoreboardMode::STAGE_INFO);
|
||||
scoreboard_->setMode(Scoreboard::Id::CENTER, Scoreboard::Mode::STAGE_INFO);
|
||||
for (const auto &player : players_) {
|
||||
scoreboard_->setName(player->getScoreBoardPanel(), player->getName());
|
||||
if (player->isWaiting()) {
|
||||
scoreboard_->setMode(player->getScoreBoardPanel(), ScoreboardMode::WAITING);
|
||||
scoreboard_->setMode(player->getScoreBoardPanel(), Scoreboard::Mode::WAITING);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1577,27 +1579,31 @@ void Game::initDifficultyVars() {
|
||||
|
||||
// Inicializa los jugadores
|
||||
void Game::initPlayers(int player_id) {
|
||||
// Crea los dos jugadores
|
||||
constexpr int PLAYER_HEIGHT = 32;
|
||||
constexpr int PLAYER_WIDTH = 32;
|
||||
const int Y = param.game.play_area.rect.h - PLAYER_HEIGHT + 1;
|
||||
|
||||
// Crea al jugador uno y lo pone en modo espera
|
||||
players_.emplace_back(std::make_unique<Player>(1, param.game.play_area.first_quarter_x - (PLAYER_WIDTH / 2), Y, demo_.enabled, param.game.play_area.rect, player_textures_[0], player_animations_));
|
||||
players_.back()->setScoreBoardPanel(SCOREBOARD_LEFT_PANEL);
|
||||
players_.back()->setScoreBoardPanel(Scoreboard::Id::LEFT);
|
||||
players_.back()->setName(Lang::getText("[SCOREBOARD] 1"));
|
||||
players_.back()->setController(getController(players_.back()->getId()));
|
||||
players_.back()->setPlayingState(Player::State::WAITING);
|
||||
|
||||
// Crea al jugador dos y lo pone en modo espera
|
||||
players_.emplace_back(std::make_unique<Player>(2, param.game.play_area.third_quarter_x - (PLAYER_WIDTH / 2), Y, demo_.enabled, param.game.play_area.rect, player_textures_[1], player_animations_));
|
||||
players_.back()->setScoreBoardPanel(SCOREBOARD_RIGHT_PANEL);
|
||||
players_.back()->setScoreBoardPanel(Scoreboard::Id::RIGHT);
|
||||
players_.back()->setName(Lang::getText("[SCOREBOARD] 2"));
|
||||
players_.back()->setController(getController(players_.back()->getId()));
|
||||
players_.back()->setPlayingState(Player::State::WAITING);
|
||||
|
||||
// Activa el jugador que coincide con el "player_id" o ambos si es "0"
|
||||
if (player_id == 0) {
|
||||
// Activa ambos jugadores
|
||||
getPlayer(1)->setPlayingState(demo_.enabled ? PlayerState::PLAYING : PlayerState::ENTERING_SCREEN);
|
||||
getPlayer(2)->setPlayingState(demo_.enabled ? PlayerState::PLAYING : PlayerState::ENTERING_SCREEN);
|
||||
getPlayer(1)->setPlayingState(demo_.enabled ? Player::State::PLAYING : Player::State::ENTERING_SCREEN);
|
||||
getPlayer(2)->setPlayingState(demo_.enabled ? Player::State::PLAYING : Player::State::ENTERING_SCREEN);
|
||||
} else {
|
||||
getPlayer(player_id)->setPlayingState(demo_.enabled ? PlayerState::PLAYING : PlayerState::ENTERING_SCREEN);
|
||||
getPlayer(player_id)->setPlayingState(demo_.enabled ? Player::State::PLAYING : Player::State::ENTERING_SCREEN);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1675,7 +1681,7 @@ void Game::updateGameStateFadeIn() {
|
||||
updateScoreboard();
|
||||
updateBackground();
|
||||
if (fade_in_->hasEnded()) {
|
||||
setState(GameState::ENTERING_PLAYER);
|
||||
setState(State::ENTERING_PLAYER);
|
||||
balloon_manager_->createTwoBigBalloons();
|
||||
evaluateAndSetMenace();
|
||||
}
|
||||
@@ -1689,7 +1695,7 @@ void Game::updateGameStateEnteringPlayer() {
|
||||
updateBackground();
|
||||
for (const auto &player : players_) {
|
||||
if (player->isPlaying()) {
|
||||
setState(GameState::SHOWING_GET_READY_MESSAGE);
|
||||
setState(State::SHOWING_GET_READY_MESSAGE);
|
||||
createMessage({paths_.at(0), paths_.at(1)}, Resource::get()->getTexture("game_text_get_ready"));
|
||||
playSound("voice_get_ready.wav");
|
||||
}
|
||||
@@ -1700,7 +1706,7 @@ void Game::updateGameStateEnteringPlayer() {
|
||||
void Game::updateGameStateShowingGetReadyMessage() {
|
||||
updateGameStatePlaying();
|
||||
if (path_sprites_.empty()) {
|
||||
setState(GameState::PLAYING);
|
||||
setState(State::PLAYING);
|
||||
}
|
||||
if (counter_ == 100) {
|
||||
playMusic();
|
||||
@@ -1746,7 +1752,7 @@ void Game::cleanVectors() {
|
||||
|
||||
// Gestiona el nivel de amenaza
|
||||
void Game::updateMenace() {
|
||||
if (state_ == GameState::PLAYING) {
|
||||
if (state_ == State::PLAYING) {
|
||||
const auto STAGE = Stage::get(Stage::number);
|
||||
const float PERCENT = Stage::power / STAGE.power_to_complete;
|
||||
const int DIFFERENCE = STAGE.max_menace - STAGE.min_menace;
|
||||
@@ -1787,7 +1793,7 @@ void Game::checkAndUpdateBalloonSpeed() {
|
||||
}
|
||||
|
||||
// Cambia el estado del juego
|
||||
void Game::setState(GameState state) {
|
||||
void Game::setState(State state) {
|
||||
state_ = state;
|
||||
counter_ = 0;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ class Game {
|
||||
|
||||
private:
|
||||
// --- Tipos internos ---
|
||||
enum class GameState {
|
||||
enum class State {
|
||||
FADE_IN,
|
||||
ENTERING_PLAYER,
|
||||
SHOWING_GET_READY_MESSAGE,
|
||||
@@ -146,7 +146,7 @@ class Game {
|
||||
int total_power_to_complete_game_; // La suma del poder necesario para completar todas las fases
|
||||
int menace_current_ = 0; // Nivel de amenaza actual
|
||||
int menace_threshold_ = 0; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el número de globos
|
||||
GameState state_ = GameState::FADE_IN; // Estado
|
||||
State state_ = State::FADE_IN; // Estado
|
||||
std::vector<std::shared_ptr<Player>> players_to_reorder_;
|
||||
Hit hit_; // Para representar colisiones en pantalla
|
||||
|
||||
@@ -155,13 +155,13 @@ class Game {
|
||||
#endif
|
||||
|
||||
// --- Ciclo principal del juego ---
|
||||
void update(); // Actualiza la lógica principal del juego
|
||||
void render(); // Renderiza todos los elementos del juego
|
||||
void checkEvents(); // Procesa los eventos del sistema en cola
|
||||
void checkState(); // Verifica y actualiza el estado actual del juego
|
||||
void setState(GameState state); // Cambia el estado del juego
|
||||
void pause(bool value); // Pausa o reanuda el juego
|
||||
void cleanVectors(); // Limpia vectores de elementos deshabilitados
|
||||
void update(); // Actualiza la lógica principal del juego
|
||||
void render(); // Renderiza todos los elementos del juego
|
||||
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 ---
|
||||
void updateGameStates(); // Actualiza todos los estados del juego
|
||||
|
||||
@@ -308,7 +308,7 @@ void Title::processPlayer2Start() {
|
||||
}
|
||||
|
||||
void Title::activatePlayerAndSetState(int player_id) {
|
||||
getPlayer(player_id)->setPlayingState(PlayerState::TITLE_ANIMATION);
|
||||
getPlayer(player_id)->setPlayingState(Player::State::TITLE_ANIMATION);
|
||||
setState(TitleState::START_HAS_BEEN_PRESSED);
|
||||
counter_ = 0;
|
||||
}
|
||||
@@ -559,10 +559,10 @@ void Title::initPlayers() {
|
||||
const int Y = param.title.press_start_position - (PLAYER_HEIGHT / 2);
|
||||
constexpr bool DEMO = false;
|
||||
players_.emplace_back(std::make_unique<Player>(1, param.game.game_area.center_x - (PLAYER_WIDTH / 2), Y, DEMO, param.game.play_area.rect, player_textures.at(0), player_animations));
|
||||
players_.back()->setPlayingState(PlayerState::TITLE_HIDDEN);
|
||||
players_.back()->setPlayingState(Player::State::TITLE_HIDDEN);
|
||||
|
||||
players_.emplace_back(std::make_unique<Player>(2, param.game.game_area.center_x - (PLAYER_WIDTH / 2), Y, DEMO, param.game.play_area.rect, player_textures.at(1), player_animations));
|
||||
players_.back()->setPlayingState(PlayerState::TITLE_HIDDEN);
|
||||
players_.back()->setPlayingState(Player::State::TITLE_HIDDEN);
|
||||
}
|
||||
|
||||
// Actualza los jugadores
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// Constructor
|
||||
Tabe::Tabe()
|
||||
: sprite_(std::make_unique<AnimatedSprite>(Resource::get()->getTexture("tabe.png"), Resource::get()->getAnimation("tabe.ani"))),
|
||||
timer_(TabeTimer(2.5F, 4.0F)) {}
|
||||
timer_(Timer(2.5F, 4.0F)) {}
|
||||
|
||||
// Actualiza la lógica
|
||||
void Tabe::update() {
|
||||
@@ -49,23 +49,23 @@ void Tabe::move() {
|
||||
const float MIN_X = param.game.game_area.rect.x - WIDTH;
|
||||
const float MAX_X = param.game.game_area.rect.x + param.game.game_area.rect.w;
|
||||
switch (destiny_) {
|
||||
case TabeDirection::TO_THE_LEFT: {
|
||||
case Direction::TO_THE_LEFT: {
|
||||
if (x_ < MIN_X) {
|
||||
disable();
|
||||
}
|
||||
if (x_ > param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH && direction_ == TabeDirection::TO_THE_RIGHT) {
|
||||
setRandomFlyPath(TabeDirection::TO_THE_LEFT, 80);
|
||||
if (x_ > param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH && direction_ == Direction::TO_THE_RIGHT) {
|
||||
setRandomFlyPath(Direction::TO_THE_LEFT, 80);
|
||||
x_ = param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TabeDirection::TO_THE_RIGHT: {
|
||||
case Direction::TO_THE_RIGHT: {
|
||||
if (x_ > MAX_X) {
|
||||
disable();
|
||||
}
|
||||
if (x_ < param.game.game_area.rect.x && direction_ == TabeDirection::TO_THE_LEFT) {
|
||||
setRandomFlyPath(TabeDirection::TO_THE_RIGHT, 80);
|
||||
if (x_ < param.game.game_area.rect.x && direction_ == Direction::TO_THE_LEFT) {
|
||||
setRandomFlyPath(Direction::TO_THE_RIGHT, 80);
|
||||
x_ = param.game.game_area.rect.x;
|
||||
}
|
||||
break;
|
||||
@@ -80,19 +80,19 @@ void Tabe::move() {
|
||||
--waiting_counter_;
|
||||
} else {
|
||||
constexpr int CHOICES = 4;
|
||||
const std::array<TabeDirection, CHOICES> LEFT = {
|
||||
TabeDirection::TO_THE_LEFT,
|
||||
TabeDirection::TO_THE_LEFT,
|
||||
TabeDirection::TO_THE_LEFT,
|
||||
TabeDirection::TO_THE_RIGHT};
|
||||
const std::array<Direction, CHOICES> LEFT = {
|
||||
Direction::TO_THE_LEFT,
|
||||
Direction::TO_THE_LEFT,
|
||||
Direction::TO_THE_LEFT,
|
||||
Direction::TO_THE_RIGHT};
|
||||
|
||||
const std::array<TabeDirection, CHOICES> RIGHT = {
|
||||
TabeDirection::TO_THE_LEFT,
|
||||
TabeDirection::TO_THE_RIGHT,
|
||||
TabeDirection::TO_THE_RIGHT,
|
||||
TabeDirection::TO_THE_RIGHT};
|
||||
const std::array<Direction, CHOICES> RIGHT = {
|
||||
Direction::TO_THE_LEFT,
|
||||
Direction::TO_THE_RIGHT,
|
||||
Direction::TO_THE_RIGHT,
|
||||
Direction::TO_THE_RIGHT};
|
||||
|
||||
const TabeDirection DIRECTION = destiny_ == TabeDirection::TO_THE_LEFT
|
||||
const Direction DIRECTION = destiny_ == Direction::TO_THE_LEFT
|
||||
? LEFT[rand() % CHOICES]
|
||||
: RIGHT[rand() % CHOICES];
|
||||
|
||||
@@ -113,10 +113,10 @@ void Tabe::enable() {
|
||||
y_ = param.game.game_area.rect.y + 20.0F;
|
||||
|
||||
// Establece una dirección aleatoria
|
||||
destiny_ = direction_ = rand() % 2 == 0 ? TabeDirection::TO_THE_LEFT : TabeDirection::TO_THE_RIGHT;
|
||||
destiny_ = direction_ = rand() % 2 == 0 ? Direction::TO_THE_LEFT : Direction::TO_THE_RIGHT;
|
||||
|
||||
// Establece la posición inicial
|
||||
x_ = (direction_ == TabeDirection::TO_THE_LEFT) ? param.game.game_area.rect.x + param.game.game_area.rect.w : param.game.game_area.rect.x - WIDTH;
|
||||
x_ = (direction_ == Direction::TO_THE_LEFT) ? param.game.game_area.rect.x + param.game.game_area.rect.w : param.game.game_area.rect.x - WIDTH;
|
||||
|
||||
// Crea una ruta de vuelo
|
||||
setRandomFlyPath(direction_, 60);
|
||||
@@ -125,7 +125,7 @@ void Tabe::enable() {
|
||||
}
|
||||
|
||||
// Establece un vuelo aleatorio
|
||||
void Tabe::setRandomFlyPath(TabeDirection direction, int lenght) {
|
||||
void Tabe::setRandomFlyPath(Direction direction, int lenght) {
|
||||
direction_ = direction;
|
||||
fly_distance_ = lenght;
|
||||
waiting_counter_ = 5 + rand() % 15;
|
||||
@@ -134,14 +134,14 @@ void Tabe::setRandomFlyPath(TabeDirection direction, int lenght) {
|
||||
constexpr float SPEED = 2.0F;
|
||||
|
||||
switch (direction) {
|
||||
case TabeDirection::TO_THE_LEFT: {
|
||||
case Direction::TO_THE_LEFT: {
|
||||
speed_ = -1.0F * SPEED;
|
||||
accel_ = -1.0F * (1 + rand() % 10) / 30.0F;
|
||||
sprite_->setFlip(SDL_FLIP_NONE);
|
||||
break;
|
||||
}
|
||||
|
||||
case TabeDirection::TO_THE_RIGHT: {
|
||||
case Direction::TO_THE_RIGHT: {
|
||||
speed_ = SPEED;
|
||||
accel_ = (1 + rand() % 10) / 30.0F;
|
||||
sprite_->setFlip(SDL_FLIP_HORIZONTAL);
|
||||
@@ -154,16 +154,16 @@ void Tabe::setRandomFlyPath(TabeDirection direction, int lenght) {
|
||||
}
|
||||
|
||||
// Establece el estado
|
||||
void Tabe::setState(TabeState state) {
|
||||
void Tabe::setState(State state) {
|
||||
if (enabled_) {
|
||||
state_ = state;
|
||||
|
||||
switch (state) {
|
||||
case TabeState::FLY:
|
||||
case State::FLY:
|
||||
sprite_->setCurrentAnimation("fly");
|
||||
break;
|
||||
|
||||
case TabeState::HIT:
|
||||
case State::HIT:
|
||||
sprite_->setCurrentAnimation("hit");
|
||||
hit_counter_ = 5;
|
||||
++number_of_hits_;
|
||||
@@ -177,10 +177,10 @@ void Tabe::setState(TabeState state) {
|
||||
|
||||
// Actualiza el estado
|
||||
void Tabe::updateState() {
|
||||
if (state_ == TabeState::HIT) {
|
||||
if (state_ == State::HIT) {
|
||||
--hit_counter_;
|
||||
if (hit_counter_ == 0) {
|
||||
setState(TabeState::FLY);
|
||||
setState(State::FLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
204
source/tabe.h
204
source/tabe.h
@@ -7,96 +7,31 @@
|
||||
|
||||
#include "animated_sprite.h" // Para AnimatedSprite
|
||||
|
||||
// --- Enumeraciones para dirección y estado ---
|
||||
enum class TabeDirection : int {
|
||||
TO_THE_LEFT = 0,
|
||||
TO_THE_RIGHT = 1,
|
||||
};
|
||||
|
||||
enum class TabeState : int {
|
||||
FLY = 0,
|
||||
HIT = 1,
|
||||
};
|
||||
|
||||
// --- Estructura para el temporizador del Tabe ---
|
||||
struct TabeTimer {
|
||||
private:
|
||||
static constexpr Uint32 MINUTES_TO_MILLISECONDS = 60000; // Factor de conversión de minutos a milisegundos
|
||||
|
||||
public:
|
||||
Uint32 time_until_next_spawn; // Tiempo restante para la próxima aparición
|
||||
Uint32 min_spawn_time; // Tiempo mínimo entre apariciones (en milisegundos)
|
||||
Uint32 max_spawn_time; // Tiempo máximo entre apariciones (en milisegundos)
|
||||
Uint32 current_time; // Tiempo actual
|
||||
Uint32 delta_time; // Diferencia de tiempo desde la última actualización
|
||||
Uint32 last_time; // Tiempo de la última actualización
|
||||
bool is_paused{false}; // Indica si el temporizador está pausado
|
||||
|
||||
// Constructor - los parámetros min_time y max_time están en mintos
|
||||
TabeTimer(float min_time, float max_time)
|
||||
: min_spawn_time(static_cast<Uint32>(min_time * MINUTES_TO_MILLISECONDS)),
|
||||
max_spawn_time(static_cast<Uint32>(max_time * MINUTES_TO_MILLISECONDS)),
|
||||
current_time(SDL_GetTicks()) {
|
||||
reset();
|
||||
}
|
||||
|
||||
// Restablece el temporizador con un nuevo tiempo hasta la próxima aparición
|
||||
void reset() {
|
||||
Uint32 range = max_spawn_time - min_spawn_time;
|
||||
time_until_next_spawn = min_spawn_time + rand() % (range + 1);
|
||||
last_time = SDL_GetTicks();
|
||||
}
|
||||
|
||||
// Actualiza el temporizador, decrementando el tiempo hasta la próxima aparición
|
||||
void update() {
|
||||
current_time = SDL_GetTicks();
|
||||
|
||||
// Solo actualizar si no está pausado
|
||||
if (!is_paused) {
|
||||
delta_time = current_time - last_time;
|
||||
|
||||
if (time_until_next_spawn > delta_time) {
|
||||
time_until_next_spawn -= delta_time;
|
||||
} else {
|
||||
time_until_next_spawn = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Siempre actualizar last_time para evitar saltos de tiempo al despausar
|
||||
last_time = current_time;
|
||||
}
|
||||
|
||||
// Pausa o reanuda el temporizador
|
||||
void setPaused(bool paused) {
|
||||
if (is_paused != paused) {
|
||||
is_paused = paused;
|
||||
// Al despausar, actualizar last_time para evitar saltos
|
||||
if (!paused) {
|
||||
last_time = SDL_GetTicks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Indica si el temporizador ha finalizado
|
||||
[[nodiscard]] auto shouldSpawn() const -> bool {
|
||||
return time_until_next_spawn == 0 && !is_paused;
|
||||
}
|
||||
};
|
||||
|
||||
// --- Clase Tabe ---
|
||||
class Tabe {
|
||||
public:
|
||||
// --- Enumeraciones para dirección y estado ---
|
||||
enum class Direction : int {
|
||||
TO_THE_LEFT = 0,
|
||||
TO_THE_RIGHT = 1,
|
||||
};
|
||||
|
||||
enum class State : int {
|
||||
FLY = 0,
|
||||
HIT = 1,
|
||||
};
|
||||
|
||||
// --- Constructores y destructor ---
|
||||
Tabe();
|
||||
~Tabe() = default;
|
||||
|
||||
// --- Métodos principales ---
|
||||
void update(); // Actualiza la lógica
|
||||
void render(); // Dibuja el objeto
|
||||
void enable(); // Habilita el objeto
|
||||
void setState(TabeState state); // Establece el estado
|
||||
auto tryToGetBonus() -> bool; // Intenta obtener el bonus
|
||||
void pauseTimer(bool value); // Detiene/activa el timer
|
||||
void update(); // Actualiza la lógica
|
||||
void render(); // Dibuja el objeto
|
||||
void enable(); // Habilita el objeto
|
||||
void setState(State state); // Establece el estado
|
||||
auto tryToGetBonus() -> bool; // Intenta obtener el bonus
|
||||
void pauseTimer(bool value); // Detiene/activa el timer
|
||||
|
||||
// --- Getters ---
|
||||
auto getCollider() -> SDL_FRect& { return sprite_->getRect(); } // Obtiene el área de colisión
|
||||
@@ -107,30 +42,95 @@ class Tabe {
|
||||
static constexpr int WIDTH = 32;
|
||||
static constexpr int HEIGHT = 32;
|
||||
|
||||
// --- Estructura para el temporizador del Tabe ---
|
||||
struct Timer {
|
||||
private:
|
||||
static constexpr Uint32 MINUTES_TO_MILLISECONDS = 60000; // Factor de conversión de minutos a milisegundos
|
||||
|
||||
public:
|
||||
Uint32 time_until_next_spawn; // Tiempo restante para la próxima aparición
|
||||
Uint32 min_spawn_time; // Tiempo mínimo entre apariciones (en milisegundos)
|
||||
Uint32 max_spawn_time; // Tiempo máximo entre apariciones (en milisegundos)
|
||||
Uint32 current_time; // Tiempo actual
|
||||
Uint32 delta_time; // Diferencia de tiempo desde la última actualización
|
||||
Uint32 last_time; // Tiempo de la última actualización
|
||||
bool is_paused{false}; // Indica si el temporizador está pausado
|
||||
|
||||
// Constructor - los parámetros min_time y max_time están en mintos
|
||||
Timer(float min_time, float max_time)
|
||||
: min_spawn_time(static_cast<Uint32>(min_time * MINUTES_TO_MILLISECONDS)),
|
||||
max_spawn_time(static_cast<Uint32>(max_time * MINUTES_TO_MILLISECONDS)),
|
||||
current_time(SDL_GetTicks()) {
|
||||
reset();
|
||||
}
|
||||
|
||||
// Restablece el temporizador con un nuevo tiempo hasta la próxima aparición
|
||||
void reset() {
|
||||
Uint32 range = max_spawn_time - min_spawn_time;
|
||||
time_until_next_spawn = min_spawn_time + rand() % (range + 1);
|
||||
last_time = SDL_GetTicks();
|
||||
}
|
||||
|
||||
// Actualiza el temporizador, decrementando el tiempo hasta la próxima aparición
|
||||
void update() {
|
||||
current_time = SDL_GetTicks();
|
||||
|
||||
// Solo actualizar si no está pausado
|
||||
if (!is_paused) {
|
||||
delta_time = current_time - last_time;
|
||||
|
||||
if (time_until_next_spawn > delta_time) {
|
||||
time_until_next_spawn -= delta_time;
|
||||
} else {
|
||||
time_until_next_spawn = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Siempre actualizar last_time para evitar saltos de tiempo al despausar
|
||||
last_time = current_time;
|
||||
}
|
||||
|
||||
// Pausa o reanuda el temporizador
|
||||
void setPaused(bool paused) {
|
||||
if (is_paused != paused) {
|
||||
is_paused = paused;
|
||||
// Al despausar, actualizar last_time para evitar saltos
|
||||
if (!paused) {
|
||||
last_time = SDL_GetTicks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Indica si el temporizador ha finalizado
|
||||
[[nodiscard]] auto shouldSpawn() const -> bool {
|
||||
return time_until_next_spawn == 0 && !is_paused;
|
||||
}
|
||||
};
|
||||
|
||||
// --- Objetos y punteros ---
|
||||
std::unique_ptr<AnimatedSprite> sprite_; // Sprite con los gráficos y animaciones
|
||||
|
||||
// --- Variables de estado ---
|
||||
float x_ = 0; // Posición X
|
||||
float y_ = 0; // Posición Y
|
||||
float speed_ = 0.0F; // Velocidad de movimiento
|
||||
float accel_ = 0.0F; // Aceleración
|
||||
int fly_distance_ = 0; // Distancia de vuelo
|
||||
int waiting_counter_ = 0; // Tiempo que pasa quieto
|
||||
bool enabled_ = false; // Indica si el objeto está activo
|
||||
TabeDirection direction_ = TabeDirection::TO_THE_LEFT; // Dirección actual
|
||||
TabeDirection destiny_ = TabeDirection::TO_THE_LEFT; // Destino
|
||||
TabeState state_ = TabeState::FLY; // Estado actual
|
||||
int hit_counter_ = 0; // Contador para el estado HIT
|
||||
int number_of_hits_ = 0; // Cantidad de disparos recibidos
|
||||
bool has_bonus_ = true; // Indica si aún tiene el bonus para soltar
|
||||
TabeTimer timer_; // Temporizador para gestionar la aparición
|
||||
float x_ = 0; // Posición X
|
||||
float y_ = 0; // Posición Y
|
||||
float speed_ = 0.0F; // Velocidad de movimiento
|
||||
float accel_ = 0.0F; // Aceleración
|
||||
int fly_distance_ = 0; // Distancia de vuelo
|
||||
int waiting_counter_ = 0; // Tiempo que pasa quieto
|
||||
bool enabled_ = false; // Indica si el objeto está activo
|
||||
Direction direction_ = Direction::TO_THE_LEFT; // Dirección actual
|
||||
Direction destiny_ = Direction::TO_THE_LEFT; // Destino
|
||||
State state_ = State::FLY; // Estado actual
|
||||
int hit_counter_ = 0; // Contador para el estado HIT
|
||||
int number_of_hits_ = 0; // Cantidad de disparos recibidos
|
||||
bool has_bonus_ = true; // Indica si aún tiene el bonus para soltar
|
||||
Timer timer_; // Temporizador para gestionar la aparición
|
||||
|
||||
// --- Métodos internos ---
|
||||
void move(); // Mueve el objeto
|
||||
void shiftSprite() { sprite_->setPos(x_, y_); } // Actualiza la posición del sprite
|
||||
void setRandomFlyPath(TabeDirection direction, int lenght); // Establece un vuelo aleatorio
|
||||
void updateState(); // Actualiza el estado
|
||||
void updateTimer(); // Actualiza el temporizador
|
||||
void disable(); // Deshabilita el objeto
|
||||
void move(); // Mueve el objeto
|
||||
void shiftSprite() { sprite_->setPos(x_, y_); } // Actualiza la posición del sprite
|
||||
void setRandomFlyPath(Direction direction, int lenght); // Establece un vuelo aleatorio
|
||||
void updateState(); // Actualiza el estado
|
||||
void updateTimer(); // Actualiza el temporizador
|
||||
void disable(); // Deshabilita el objeto
|
||||
};
|
||||
Reference in New Issue
Block a user