#pragma once #include // Para SDL_FRect #include // Para Uint32 #include // Para SDL_GetTicks #include // Para rand #include // Para unique_ptr #include "animated_sprite.h" // Para AnimatedSprite enum class TabeDirection : int { TO_THE_LEFT = 0, TO_THE_RIGHT = 1, }; enum class TabeState : int { FLY = 0, HIT = 1, }; struct TabeTimer { Uint32 time_until_next_spawn; // Tiempo restante para la próxima aparición Uint32 min_spawn_time; // Tiempo mínimo entre apariciones Uint32 max_spawn_time; // Tiempo máximo entre apariciones 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 // Constructor TabeTimer(float minTime, float maxTime) : min_spawn_time(minTime * 60000), max_spawn_time(maxTime * 60000), 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(); delta_time = current_time - last_time; last_time = current_time; if (time_until_next_spawn > delta_time) { time_until_next_spawn -= delta_time; } else { time_until_next_spawn = 0; } } // Indica si el temporizador ha finalizado bool should_spawn() const { return time_until_next_spawn == 0; } }; // Clase Tabe class Tabe { private: // Constantes static constexpr int WIDTH_ = 32; static constexpr int HEIGHT_ = 32; // Punteros std::unique_ptr sprite_; // Sprite con los graficos y animaciones // Variables float x_ = 0; // Posición del objeto float y_ = 0; // Posición del objeto float speed_ = 0.0f; // Velocidad de movimiento del objeto float accel_ = 0.0f; // Aceleración del objeto int fly_distance_ = 0; // Distancia de vuelo int waiting_counter_ = 0; // Tiempo que pasa quieto el objeto bool enabled_ = false; // Indica si el objeto está activo TabeDirection direction_ = TabeDirection::TO_THE_LEFT; // Dirección del objeto TabeDirection destiny_ = TabeDirection::TO_THE_LEFT; // Destino del objeto TabeState state_ = TabeState::FLY; // Estado int hit_counter_ = 0; // Contador para el estado HIT int number_of_hits_ = 0; // Cantidad de disparos que ha recibido bool has_bonus_ = true; // Indica si el Tabe aun tiene el bonus para soltar TabeTimer timer_; // Temporizador para gestionar la aparición del Tabe // Mueve el objeto void move(); // Actualiza la posición del sprite void shiftSprite() { sprite_->setPos(x_, y_); } // Establece un vuelo aleatorio void setRandomFlyPath(TabeDirection direction, int lenght); // Actualiza el estado void updateState(); // Actualiza el temporizador void updateTimer(); // Deshabilita el objeto void disable(); public: // Constructor Tabe(); // Destructor ~Tabe() = default; // Actualiza la lógica void update(); // Dibuja el objeto void render(); // Habilita el objeto void enable(); // Establece el estado void setState(TabeState state); // Intenta obtener el bonus bool tryToGetBonus(); // Obtiene el area de colisión SDL_FRect &getCollider() { return sprite_->getRect(); } // Getters bool isEnabled() const { return enabled_; } };