#pragma once #include // Para Uint8, Uint16, SDL_FRect, Uint32 #include // Para shared_ptr, unique_ptr #include // Para basic_string, string #include // Para vector #include "animated_sprite.h" // Para AnimatedSprite #include "utils.h" // Para Circle class Texture; // --- Constantes relacionadas con globos --- constexpr int MAX_BOUNCE = 10; // Cantidad de elementos del vector de deformación constexpr int BALLOON_SCORE[] = {50, 100, 200, 400}; constexpr int BALLOON_POWER[] = {1, 3, 7, 15}; constexpr int BALLOON_MENACE[] = {1, 2, 4, 8}; constexpr int BALLOON_SIZE[] = {10, 16, 26, 48, 49}; const std::string BALLOON_BOUNCING_SOUND[] = {"bubble1.wav", "bubble2.wav", "bubble3.wav", "bubble4.wav"}; const std::string BALLOON_POPPING_SOUND[] = {"balloon1.wav", "balloon2.wav", "balloon3.wav", "balloon4.wav"}; enum class BalloonSize : Uint8 { SIZE1 = 0, SIZE2 = 1, SIZE3 = 2, SIZE4 = 3, }; enum class BalloonType : Uint8 { BALLOON = 0, FLOATER = 1, POWERBALL = 2, }; constexpr float BALLOON_VELX_POSITIVE = 0.7f; constexpr float BALLOON_VELX_NEGATIVE = -0.7f; constexpr int BALLOON_MOVING_ANIMATION = 0; constexpr int BALLOON_POP_ANIMATION = 1; constexpr int BALLOON_BORN_ANIMATION = 2; constexpr float BALLOON_SPEED[] = {0.60f, 0.70f, 0.80f, 0.90f, 1.00f}; constexpr int POWERBALL_SCREENPOWER_MINIMUM = 10; constexpr int POWERBALL_COUNTER = 8; // --- Clase Balloon --- class Balloon { public: // --- Constructores y destructor --- Balloon( float x, float y, BalloonType type, BalloonSize size, float vel_x, float speed, Uint16 creation_timer, SDL_FRect play_area, std::shared_ptr texture, const std::vector &animation); ~Balloon() = default; // --- Métodos principales --- void alignTo(int x); // Centra el globo en la posición X void render(); // Pinta el globo en la pantalla void move(); // Actualiza la posición y estados del globo void update(); // Actualiza el globo (posición, animación, contadores) void stop(); // Detiene el globo void start(); // Pone el globo en movimiento void pop(bool should_sound = false); // Explota el globo // --- Métodos de color --- void useReverseColor(); // Pone el color alternativo en el globo void useNormalColor(); // Pone el color normal en el globo // --- Getters --- float getPosX() const { return x_; } float getPosY() const { return y_; } int getWidth() const { return w_; } int getHeight() const { return h_; } BalloonSize getSize() const { return size_; } BalloonType getType() const { return type_; } Uint16 getScore() const { return score_; } Circle &getCollider() { return collider_; } Uint8 getMenace() const { return isEnabled() ? menace_ : 0; } Uint8 getPower() const { return power_; } bool isStopped() const { return stopped_; } bool isPowerBall() const { return type_ == BalloonType::POWERBALL; } bool isInvulnerable() const { return invulnerable_; } bool isBeingCreated() const { return being_created_; } bool isEnabled() const { return enabled_; } bool isUsingReversedColor() { return use_reversed_colors_; } bool canBePopped() const { return !isBeingCreated(); } // --- Setters --- void setVelY(float vel_y) { vy_ = vel_y; } void setSpeed(float speed) { speed_ = speed; } void setInvulnerable(bool value) { invulnerable_ = value; } void setBouncingSound(bool value) { bouncing_sound_enabled_ = value; } void setPoppingSound(bool value) { poping_sound_enabled_ = value; } void setSound(bool value) { sound_enabled_ = value; } private: // --- Estructura para el efecto de rebote --- struct Bouncing { bool enabled = false; // Si el efecto está activo Uint8 counter = 0; // Contador para el efecto Uint8 speed = 2; // Velocidad del efecto float zoomW = 1.0f; // Zoom en anchura float zoomH = 1.0f; // Zoom en altura float despX = 0.0f; // Desplazamiento X antes de pintar float despY = 0.0f; // Desplazamiento Y antes de pintar float w[MAX_BOUNCE] = {1.10f, 1.05f, 1.00f, 0.95f, 0.90f, 0.95f, 1.00f, 1.02f, 1.05f, 1.02f}; // Zoom ancho float h[MAX_BOUNCE] = {0.90f, 0.95f, 1.00f, 1.05f, 1.10f, 1.05f, 1.00f, 0.98f, 0.95f, 0.98f}; // Zoom alto Bouncing() = default; void reset() { counter = 0; zoomW = 1.0f; zoomH = 1.0f; despX = 0.0f; despY = 0.0f; } } bouncing_; // --- Objetos y punteros --- std::unique_ptr sprite_; // Sprite del objeto globo // --- Variables de estado y físicas --- float x_; // Posición X float y_; // Posición Y float w_; // Ancho float h_; // Alto float vx_; // Velocidad X float vy_; // Velocidad Y float gravity_; // Aceleración en Y float default_vy_; // Velocidad inicial al rebotar float max_vy_; // Máxima velocidad en Y bool being_created_; // Si el globo se está creando bool enabled_ = true; // Si el globo está activo bool invulnerable_; // Si el globo es invulnerable bool stopped_; // Si el globo está parado bool use_reversed_colors_ = false; // Si se usa el color alternativo Circle collider_; // Círculo de colisión Uint16 creation_counter_; // Temporizador de creación Uint16 creation_counter_ini_; // Valor inicial del temporizador de creación Uint16 score_; // Puntos al destruir el globo BalloonType type_; // Tipo de globo BalloonSize size_; // Tamaño de globo Uint8 menace_; // Amenaza que genera el globo Uint32 counter_ = 0; // Contador interno float travel_y_ = 1.0f; // Distancia a recorrer en Y antes de aplicar gravedad float speed_; // Velocidad del globo Uint8 power_; // Poder que alberga el globo SDL_FRect play_area_; // Zona de movimiento del globo std::string bouncing_sound_; // Archivo de sonido al rebotar std::string popping_sound_; // Archivo de sonido al explotar bool bouncing_sound_enabled_ = false; // Si debe sonar el globo al rebotar bool poping_sound_enabled_ = true; // Si debe sonar el globo al explotar bool sound_enabled_ = true; // Indica si los globos deben hacer algun sonido // --- Métodos internos --- void shiftColliders(); // Alinea el círculo de colisión void shiftSprite(); // Alinea el sprite void zoomSprite(); // Establece el nivel de zoom del sprite void enableBounce(); // Activa el efecto de rebote void disableBounce(); // Detiene el efecto de rebote void updateBounce(); // Aplica el efecto de rebote void updateState(); // Actualiza los estados del globo void setAnimation(); // Establece la animación correspondiente void playSound(const std::string &name); // Reproduce sonido };