// IWYU pragma: no_include #include "tabe.h" #include // Para SDL_FLIP_HORIZONTAL, SDL_FLIP_NONE #include // Para rand, abs #include "jail_audio.h" // Para JA_PlaySound #include "param.h" // Para Param, ParamGame, param #include "resource.h" // Para Resource #include "utils.h" // Para Zone // Constructor Tabe::Tabe() : sprite_(std::make_unique(Resource::get()->getTexture("tabe.png"), Resource::get()->getAnimation("tabe.ani"))) {} // Actualiza la lógica void Tabe::update() { if (enabled_) { sprite_->update(); move(); } } // Dibuja el objeto void Tabe::render() { if (enabled_) { sprite_->render(); } } // Mueve el objeto void Tabe::move() { const int x = static_cast(x_); speed_ += accel_; x_ += speed_; fly_distance_ -= std::abs(x - static_cast(x_)); // Comprueba si sale por los bordes 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: { if (x_ < min_x) { enabled_ = false; } 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); x_ = param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH_; } break; } case TabeDirection::TO_THE_RIGHT: { if (x_ > max_x) { enabled_ = false; } if (x_ < param.game.game_area.rect.x && direction_ == TabeDirection::TO_THE_LEFT) { setRandomFlyPath(TabeDirection::TO_THE_RIGHT, 80); x_ = param.game.game_area.rect.x; } break; } default: break; } if (fly_distance_ <= 0) { if (waiting_counter_ > 0) { accel_ = speed_ = 0.0f; --waiting_counter_; } else { constexpr int CHOICES = 4; const TabeDirection left[CHOICES] = {TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_RIGHT}; const TabeDirection right[CHOICES] = {TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_RIGHT, TabeDirection::TO_THE_RIGHT, TabeDirection::TO_THE_RIGHT}; const TabeDirection direction = destiny_ == TabeDirection::TO_THE_LEFT ? left[rand() % CHOICES] : right[rand() % CHOICES]; setRandomFlyPath(direction, 20 + rand() % 40); } } shiftSprite(); } // Habilita el objeto void Tabe::enable() { if (!enabled_) { enabled_ = true; y_ = 20.0f; // Establece una dirección aleatoria destiny_ = direction_ = rand() % 2 == 0 ? TabeDirection::TO_THE_LEFT : TabeDirection::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_; // Crea una ruta de vuelo setRandomFlyPath(direction_, 60); shiftSprite(); } } // Establece un vuelo aleatorio void Tabe::setRandomFlyPath(TabeDirection direction, int lenght) { direction_ = direction; fly_distance_ = lenght; waiting_counter_ = 5 + rand() % 15; JA_PlaySound(Resource::get()->getSound("tabe.wav")); constexpr float SPEED = 2.0f; switch (direction) { case TabeDirection::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: { speed_ = SPEED; accel_ = (1 + rand() % 10) / 30.0f; sprite_->setFlip(SDL_FLIP_HORIZONTAL); break; } default: break; } }