#pragma once #include #include // for string #include // for vector #include "utils/utils.h" // for Circle class AnimatedSprite; class Texture; // Clase Balloon class Balloon { public: // Tipos de globo static constexpr int BALLOON_1 = 1; static constexpr int BALLOON_2 = 2; static constexpr int BALLOON_3 = 3; static constexpr int BALLOON_4 = 4; static constexpr int HEXAGON_1 = 5; static constexpr int HEXAGON_2 = 6; static constexpr int HEXAGON_3 = 7; static constexpr int HEXAGON_4 = 8; static constexpr int POWER_BALL = 9; // Puntos de globo static constexpr int SCORE_1 = 50; static constexpr int SCORE_2 = 100; static constexpr int SCORE_3 = 200; static constexpr int SCORE_4 = 400; // Tamaños de globo static constexpr int SIZE_1 = 1; static constexpr int SIZE_2 = 2; static constexpr int SIZE_3 = 3; static constexpr int SIZE_4 = 4; // Clases de globo static constexpr int BALLOON_CLASS = 0; static constexpr int HEXAGON_CLASS = 1; // Velocidad del globo static constexpr float VELX_POSITIVE = 0.7F; static constexpr float VELX_NEGATIVE = -0.7F; // Velocidades a las que se mueven los globos static constexpr float SPEED_1 = 0.60F; static constexpr float SPEED_2 = 0.70F; static constexpr float SPEED_3 = 0.80F; static constexpr float SPEED_4 = 0.90F; static constexpr float SPEED_5 = 1.00F; // Tamaño de los globos static constexpr int WIDTH_1 = 8; static constexpr int WIDTH_2 = 13; static constexpr int WIDTH_3 = 21; static constexpr int WIDTH_4 = 37; // PowerBall static constexpr int POWERBALL_SCREENPOWER_MINIMUM = 10; static constexpr int POWERBALL_COUNTER = 8; Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 creationtimer, Texture *texture, const std::vector *animation, SDL_Renderer *renderer); // Constructor ~Balloon(); // Destructor Balloon(const Balloon &) = delete; auto operator=(const Balloon &) -> Balloon & = delete; void allignTo(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 (frame-based) void move(float dt_s); // Actualiza la posición y estados del globo (time-based) void disable(); // Deshabilita el globo y pone a cero todos los valores void pop(); // Explosiona el globo void update(); // Actualiza al globo (frame-based) void update(float dt_s); // Actualiza al globo (time-based) [[nodiscard]] auto isEnabled() const -> bool; // Comprueba si el globo está habilitado [[nodiscard]] auto isStopped() const -> bool; // Obtiene del valor de la variable [[nodiscard]] auto isBlinking() const -> bool; // Obtiene del valor de la variable [[nodiscard]] auto isVisible() const -> bool; // Obtiene del valor de la variable [[nodiscard]] auto isInvulnerable() const -> bool; // Obtiene del valor de la variable [[nodiscard]] auto isBeingCreated() const -> bool; // Obtiene del valor de la variable [[nodiscard]] auto isPopping() const -> bool; // Obtiene del valor de la variable [[nodiscard]] auto getPosX() const -> float; // Obtiene del valor de la variable [[nodiscard]] auto getPosY() const -> float; // Obtiene del valor de la variable [[nodiscard]] auto getVelY() const -> float; // Obtiene del valor de la variable [[nodiscard]] auto getWidth() const -> int; // Obtiene del valor de la variable [[nodiscard]] auto getHeight() const -> int; // Obtiene del valor de la variable [[nodiscard]] auto getKind() const -> int; // Obtiene del valor de la variable [[nodiscard]] auto getSize() const -> Uint8; // Obtiene del valor de la variable [[nodiscard]] auto getClass() const -> Uint8; // Obtiene la clase a la que pertenece el globo [[nodiscard]] auto getStoppedTimer() const -> Uint16; // Obtiene del valor de la variable [[nodiscard]] auto getScore() const -> Uint16; // Obtiene del valor de la variable [[nodiscard]] auto getMenace() const -> Uint8; // Obtiene le valor de la variable [[nodiscard]] auto getPower() const -> Uint8; // Obtiene le valor de la variable void setVelY(float vel_y); // Establece el valor de la variable void setSpeed(float speed); // Establece el valor de la variable void setStop(bool state); // Establece el valor de la variable void setBlink(bool value); // Establece el valor de la variable void setVisible(bool value); // Establece el valor de la variable void setInvulnerable(bool value); // Establece el valor de la variable void setPopping(bool value); // Establece el valor de la variable void setStoppedTimer(Uint16 time); // Establece el valor de la variable auto getCollider() -> Circle &; // Obtiene el circulo de colisión private: // Cantidad de elementos del vector con los valores de la deformación del globo al rebotar static constexpr int MAX_BOUNCE = 10; // Time-based: la creació "desplaça" el globus cada 10 frames a 60Hz ⇒ 1/6 s. static constexpr float CREATION_STEP_S = 10.0F / 60.0F; // Time-based: el bounce avança w/h cada `speed_` frames a 60Hz; mantenim el mateix temps per pas. static constexpr float BOUNCE_STEP_S = 1.0F / 60.0F; // 1 frame // Estructura para las variables para el efecto de los rebotes struct Bouncing { bool enabled; // Si el efecto está activo Uint8 counter; // Countador para el efecto Uint8 speed; // Velocidad a la que transcurre el efecto float zoom_width; // Zoom aplicado a la anchura float zoom_height; // Zoom aplicado a la altura float desp_x; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom float desp_y; // Desplazamiento de pixeles en el eje Y antes de pintar el objeto con zoom std::vector w; // Vector con los valores de zoom para el ancho del globo std::vector h; // Vector con los valores de zoom para el alto del globo }; // Objetos y punteros AnimatedSprite *sprite_; // Sprite del objeto globo // Variables float pos_x_; // Posición en el eje X float pos_y_; // Posición en el eje Y Uint8 width_; // Ancho Uint8 height_; // Alto float vel_x_; // Velocidad en X (frame-based: px/frame) float vel_y_; // Velocidad en Y (frame-based: px/frame) float gravity_; // Aceleración Y (frame-based: px/frame²) float default_vel_y_; // Velocitat inicial al rebotar contra el terra (frame-based) float max_vel_y_; // Velocitat màxima en Y (frame-based) float vel_x_s_{0.0F}; // Velocidad en X (time-based: px/s) float vel_y_s_{0.0F}; // Velocidad en Y (time-based: px/s) float gravity_s_{0.0F}; // Aceleración Y (time-based: px/s²) float default_vel_y_s_{0.0F}; // Velocitat inicial al rebotar (time-based) float max_vel_y_s_{0.0F}; // Velocitat màxima en Y (time-based) bool being_created_; // Indica si el globo se está creando bool blinking_; // Indica si el globo está intermitente bool enabled_; // Indica si el globo esta activo bool invulnerable_; // Indica si el globo es invulnerable bool popping_; // Indica si el globo está explotando bool stopped_; // Indica si el globo está parado bool visible_; // Indica si el globo es visible Circle collider_; // Circulo de colisión del objeto Uint16 creation_counter_; // Temporizador (frame-based) Uint16 creation_counter_ini_; // Valor inicial del temporizador (frames) float creation_counter_s_{0.0F}; // Temporizador (time-based) float creation_counter_ini_s_{0.0F}; // Valor inicial del temporizador (segons) float creation_phase_s_{0.0F}; // Acumulador de fase per als steps de creació (time-based) Uint16 score_; // Puntos que da el globo al ser destruido Uint16 stopped_counter_; // Contador (frame-based) float stopped_counter_s_{0.0F}; // Contador (time-based) Uint8 kind_; // Tipo de globo Uint8 menace_; // Cantidad de amenaza que genera el globo Uint32 counter_; // Contador interno (legacy, no usat per cap lector) float travel_y_; // Acumulador per a aplicar la gravetat (frame-based) float speed_; // Tempo del joc (multiplicador adimensional, frame i time-based) Uint8 size_; // Tamaño del globo Uint8 power_; // Cantidad de poder que alberga el globo Bouncing bouncing_; // Contiene las variables para el efecto de rebote float bounce_phase_s_{0.0F}; // Fase del bounce (time-based) void updateColliders(); // Alinea el circulo de colisión con la posición del objeto globo void bounceStart(); // Activa el efecto void bounceStop(); // Detiene el efecto void updateBounce(); // Aplica el efecto (frame-based) void updateBounce(float dt_s); // Aplica el efecto (time-based) void updateAnimation(); // Establece la animación correspondiente (frame-based) void updateAnimation(float dt_s); // Establece la animación correspondiente (time-based) void setBeingCreated(bool value); // Establece el valor de la variable void updateState(); // Actualiza los estados del globo (frame-based) void updateState(float dt_s); // Actualiza los estados del globo (time-based) // Helpers de updateState, uno por cada rama de estado void updateStatePopping(); void updateStateBeingCreated(); void updateStateBeingCreated(float dt_s); void updateStateStopped(); void updateStateStopped(float dt_s); };