#pragma once #include #include // Para SDL_FRect #include // Para Uint8, Uint16, Uint32 #include // Para shared_ptr, unique_ptr #include // Para string #include // Para vector #include "animated_sprite.h" // Para AnimatedSprite #include "utils.h" // Para Circle class Texture; // lines 9-9 // Cantidad de elementos del vector con los valores de la deformación del globo al rebotar constexpr int MAX_BOUNCE = 10; // Puntos de globo 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_SOUND[] = {"bubble1.wav", "bubble2.wav", "bubble3.wav", "bubble4.wav"}; // Tamaños de globo enum class BalloonSize : Uint8 { SIZE1 = 0, SIZE2 = 1, SIZE3 = 2, SIZE4 = 3, }; // Clases de globo enum class BalloonType : Uint8 { BALLOON = 0, FLOATER = 1, POWERBALL = 2, }; // Velocidad del globo constexpr float BALLOON_VELX_POSITIVE = 0.7f; constexpr float BALLOON_VELX_NEGATIVE = -0.7f; // Indice para las animaciones de los globos constexpr int BALLOON_MOVING_ANIMATION = 0; constexpr int BALLOON_POP_ANIMATION = 1; constexpr int BALLOON_BORN_ANIMATION = 2; // Velocidades a las que se mueven los globos constexpr float BALLOON_SPEED[] = {0.60f, 0.70f, 0.80f, 0.90f, 1.00f}; // PowerBall constexpr int POWERBALL_SCREENPOWER_MINIMUM = 10; constexpr int POWERBALL_COUNTER = 8; // Clase Balloon class Balloon { private: // Estructura para el efecto de los rebotes en los globos struct Bouncing { bool enabled = false; // Si el efecto está activo Uint8 counter = 0; // Contador para el efecto Uint8 speed = 2; // Velocidad a la que transcurre el efecto float zoomW = 1.0f; // Zoom aplicado a la anchura float zoomH = 1.0f; // Zoom aplicado a la altura float despX = 0.0f; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom float despY = 0.0f; // Desplazamiento de pixeles en el eje Y antes de pintar el objeto con zoom float w[MAX_BOUNCE] = {1.10f, 1.05f, 1.00f, 0.95f, 0.90f, 0.95f, 1.00f, 1.02f, 1.05f, 1.02f}; // Vector con los valores de zoom para el ancho del globo float h[MAX_BOUNCE] = {0.90f, 0.95f, 1.00f, 1.05f, 1.10f, 1.05f, 1.00f, 0.98f, 0.95f, 0.98f}; // Vector con los valores de zoom para el alto del globo // Constructor por defecto Bouncing() = default; // Método reset 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 float x_; // Posición en el eje X float y_; // Posición en el eje Y float w_; // Ancho float h_; // Alto float vx_; // Velocidad en el eje X. Cantidad de pixeles a desplazarse float vy_; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse float gravity_; // Aceleración en el eje Y. Modifica la velocidad float default_vy_; // Velocidad inicial que tienen al rebotar contra el suelo float max_vy_; // Máxima velocidad que puede alcanzar el objeto en el eje Y bool being_created_; // Indica si el globo se está creando bool enabled_ = true; // Indica si el globo esta activo bool invulnerable_; // Indica si el globo es invulnerable bool stopped_; // Indica si el globo está parado bool use_reversed_colors_ = false; // Indica si se ha de usar el color secundario del globo como color principal Circle collider_; // Circulo de colisión del objeto Uint16 creation_counter_; // Temporizador para controlar el estado "creandose" Uint16 creation_counter_ini_; // Valor inicial para el temporizador para controlar el estado "creandose" Uint16 score_; // Puntos que da el globo al ser destruido BalloonType type_; // Clase de globo BalloonSize size_; // Tamaño del globo Uint8 menace_; // Cantidad de amenaza que genera el globo Uint32 counter_ = 0; // Contador interno float travel_y_ = 1.0f; // Distancia que ha de recorrer el globo en el eje Y antes de que se le aplique la gravedad float speed_; // Velocidad a la que se mueven los globos Uint8 power_; // Cantidad de poder que alberga el globo SDL_FRect play_area_; // Zona por donde se puede mover el globo std::string sound_; // Archivo de sonido que hace el globo al rebotar bool sound_enabled_ = false; // Indica si ha de sonar el sonido del globo al rebotar // Alinea el circulo de colisión con la posición del objeto globo void shiftColliders(); // Alinea el sprite con la posición del objeto globo void shiftSprite(); // Establece el nivel de zoom del sprite void zoomSprite(); // Activa el efecto void enableBounce(); // Detiene el efecto void disableBounce(); // Aplica el efecto void updateBounce(); // Actualiza los estados del globo void updateState(); // Establece la animación correspondiente void setAnimation(); // Reproduce el sonido al rebotar void playSound(); public: // Constructor 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); // Destructor ~Balloon() = default; // Centra el globo en la posición X void alignTo(int x); // Pinta el globo en la pantalla void render(); // Actualiza la posición y estados del globo void move(); // Actualiza al globo a su posicion, animación y controla los contadores void update(); // Detiene el globo void stop(); // Pone el globo en movimiento void start(); // Pone el color alternativo en el globo void useReverseColor(); // Pone el color normal en el globo void useNormalColor(); // 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 setSound(bool value) { sound_enabled_ = value; } void disable() { enabled_ = false; } };