#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 // --- 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 { 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 { public: // --- 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 bool tryToGetBonus(); // Intenta obtener el bonus // --- Getters --- SDL_FRect &getCollider() { return sprite_->getRect(); } // Obtiene el área de colisión bool isEnabled() const { return enabled_; } // Indica si el objeto está activo private: // --- Constantes --- static constexpr int WIDTH_ = 32; static constexpr int HEIGHT_ = 32; // --- Objetos y punteros --- std::unique_ptr 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 // --- 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 };