From 5f170ee44ecae30af3705a76209d7a9dbac20108 Mon Sep 17 00:00:00 2001 From: Sergio Date: Wed, 23 Jul 2025 18:03:49 +0200 Subject: [PATCH] balloon: readability-function-cognitive-complexity balloon: eliminat l'efecte de rebot per als globos mes xicotets moving_sprite: canviats variables i metodes zoomW a horizontal_zoom i zoomH a vertical_zoom --- source/balloon.cpp | 204 ++++++++++++++++++++++----------------- source/balloon.h | 50 +++++++--- source/moving_sprite.cpp | 18 ++-- source/moving_sprite.h | 13 +-- 4 files changed, 166 insertions(+), 119 deletions(-) diff --git a/source/balloon.cpp b/source/balloon.cpp index dd8b8fe..7cb1da7 100644 --- a/source/balloon.cpp +++ b/source/balloon.cpp @@ -140,80 +140,102 @@ void Balloon::render() { // Actualiza la posición y estados del globo void Balloon::move() { - // Comprueba si se puede mover - if (!isStopped()) { - // Mueve el globo en horizontal - x_ += vx_ * speed_; + if (isStopped()) { + return; + } - // Colisión en las partes laterales de la zona de juego - const int CLIP = 2; - const float MIN_X = play_area_.x - CLIP; - const float MAX_X = play_area_.x + play_area_.w - w_ + CLIP; - if (x_ < MIN_X || x_ > MAX_X) { - if (bouncing_sound_enabled_) { - playSound(bouncing_sound_); - } - x_ = std::clamp(x_, MIN_X, MAX_X); - vx_ = -vx_; - // Activa el efecto de rebote o invierte la rotación - if (type_ == BalloonType::POWERBALL) { - sprite_->switchRotate(); - } else { - enableBounce(); - } + handleHorizontalMovement(); + handleVerticalMovement(); + applyGravity(); +} + +void Balloon::handleHorizontalMovement() { + x_ += vx_ * speed_; + + const int CLIP = 2; + const float MIN_X = play_area_.x - CLIP; + const float MAX_X = play_area_.x + play_area_.w - w_ + CLIP; + + if (isOutOfHorizontalBounds(MIN_X, MAX_X)) { + handleHorizontalBounce(MIN_X, MAX_X); + } +} + +void Balloon::handleVerticalMovement() { + y_ += vy_ * speed_; + + if (shouldCheckTopCollision()) { + handleTopCollision(); + } + + handleBottomCollision(); +} + +bool Balloon::isOutOfHorizontalBounds(float minX, float maxX) const { + return x_ < minX || x_ > maxX; +} + +void Balloon::handleHorizontalBounce(float minX, float maxX) { + playBouncingSound(); + x_ = std::clamp(x_, minX, maxX); + vx_ = -vx_; + + if (type_ == BalloonType::POWERBALL) { + sprite_->switchRotate(); + } else { + enableBounceEffect(); + } +} + +bool Balloon::shouldCheckTopCollision() const { + // Colisión en la parte superior solo si el globo va de subida + return vy_ < 0; +} + +void Balloon::handleTopCollision() { + const int MIN_Y = play_area_.y; + if (y_ < MIN_Y) { + playBouncingSound(); + y_ = MIN_Y; + vy_ = -vy_; + enableBounceEffect(); + } +} + +void Balloon::handleBottomCollision() { + const int MAX_Y = play_area_.y + play_area_.h - h_; + if (y_ > MAX_Y) { + playBouncingSound(); + y_ = MAX_Y; + vy_ = -default_vy_; + + if (type_ != BalloonType::POWERBALL) { + enableBounceEffect(); + } else { + setInvulnerable(false); } + } +} - // Mueve el globo en vertical - y_ += vy_ * speed_; +void Balloon::applyGravity() { + /* + Para aplicar la gravedad, el diseño original la aplicaba en cada iteración del bucle + Al añadir el modificador de velocidad se reduce la distancia que recorre el objeto y por + tanto recibe mas gravedad. Para solucionarlo se va a aplicar la gravedad cuando se haya + recorrido una distancia igual a la velocidad en Y, que era el cálculo inicial + */ - // Colisión en la parte superior solo si el globo va de subida - if (vy_ < 0) { - const int MIN_Y = play_area_.y; - if (y_ < MIN_Y) { - if (bouncing_sound_enabled_) { - playSound(bouncing_sound_); - } - y_ = MIN_Y; - vy_ = -vy_; - enableBounce(); - } - } + travel_y_ += speed_; - // Colisión en la parte inferior de la zona de juego - const int MAX_Y = play_area_.y + play_area_.h - h_; - if (y_ > MAX_Y) { - if (bouncing_sound_enabled_) { - playSound(bouncing_sound_); - } - y_ = MAX_Y; - vy_ = -default_vy_; - if (type_ != BalloonType::POWERBALL) { - enableBounce(); - } else { - setInvulnerable(false); - } - } + if (travel_y_ >= 1.0F) { + travel_y_ -= 1.0F; + vy_ += gravity_; + } +} - /* - - Para aplicar la gravedad, el diseño original la aplicaba en cada iteración del bucle - Al añadir el modificador de velocidad se reduce la distancia que recorre el objeto y por - tanto recibe mas gravedad. Para solucionarlo se va a aplicar la gravedad cuando se haya - recorrido una distancia igual a la velocidad en Y, que era el cálculo inicial - - */ - - // Incrementa la variable que calcula la distancia acumulada en Y - travel_y_ += speed_; - - // Si la distancia acumulada en Y es igual a la velocidad, se aplica la gravedad - if (travel_y_ >= 1.0F) { - // Quita el excedente - travel_y_ -= 1.0F; - - // Aplica la gravedad al objeto sin pasarse de una velocidad máxima - vy_ += gravity_; - } +void Balloon::playBouncingSound() { + if (bouncing_sound_enabled_) { + playSound(bouncing_sound_); } } @@ -221,7 +243,7 @@ void Balloon::move() { void Balloon::update() { move(); updateState(); - updateBounce(); + updateBounceEffect(); shiftSprite(); shiftColliders(); sprite_->update(); @@ -321,37 +343,41 @@ void Balloon::shiftSprite() { sprite_->setPosY(y_); } -// Establece el nivel de zoom del sprite -void Balloon::zoomSprite() { - sprite_->setZoomW(bouncing_.horizontal_zoom); - sprite_->setZoomH(bouncing_.verical_zoom); +// Aplica la deformación visual causada por el efecto de rebote +void Balloon::applyBounceEffect() { + sprite_->setHorizontalZoom(bounce_effect_.horizontal_zoom); + sprite_->setVerticalZoom(bounce_effect_.verical_zoom); } // Activa el efecto -void Balloon::enableBounce() { - bouncing_.enabled = true; - bouncing_.reset(); - zoomSprite(); +void Balloon::enableBounceEffect() { + // Los globos pequeños no tienen efecto de rebote + if (size_ == BalloonSize::SIZE1) { + return; + } + bounce_effect_.enabled = true; + bounce_effect_.reset(); + applyBounceEffect(); } // Detiene el efecto -void Balloon::disableBounce() { - bouncing_.enabled = false; - bouncing_.reset(); - zoomSprite(); +void Balloon::disableBounceEffect() { + bounce_effect_.enabled = false; + bounce_effect_.reset(); + applyBounceEffect(); } // Aplica el efecto -void Balloon::updateBounce() { - if (bouncing_.enabled) { - const int INDEX = bouncing_.counter / bouncing_.speed; - bouncing_.horizontal_zoom = bouncing_.horizontal_zoom_values[INDEX]; - bouncing_.verical_zoom = bouncing_.vertical_zoom_values[INDEX]; +void Balloon::updateBounceEffect() { + if (bounce_effect_.enabled) { + const int INDEX = bounce_effect_.counter / bounce_effect_.speed; + bounce_effect_.horizontal_zoom = bounce_effect_.horizontal_zoom_values[INDEX]; + bounce_effect_.verical_zoom = bounce_effect_.vertical_zoom_values[INDEX]; - zoomSprite(); + applyBounceEffect(); - if (++bouncing_.counter / bouncing_.speed >= MAX_BOUNCE) { - disableBounce(); + if (++bounce_effect_.counter / bounce_effect_.speed >= MAX_BOUNCE) { + disableBounceEffect(); } } } diff --git a/source/balloon.h b/source/balloon.h index 8a1777f..422881a 100644 --- a/source/balloon.h +++ b/source/balloon.h @@ -1,10 +1,11 @@ #pragma once -#include // Para Uint8, Uint16, SDL_FRect, Uint32 -#include // Para array -#include // Para allocator, shared_ptr, unique_ptr -#include // Para basic_string, string -#include // Para vector +#include // Para Uint8, Uint16, SDL_FRect, Uint32 + +#include // Para array +#include // Para allocator, shared_ptr, unique_ptr +#include // Para basic_string, string +#include // Para vector #include "animated_sprite.h" // Para AnimatedSprite #include "utils.h" // Para Circle @@ -129,7 +130,7 @@ class Balloon { desp_x = 0.0F; desp_y = 0.0F; } - } bouncing_; + } bounce_effect_; // --- Objetos y punteros --- std::unique_ptr sprite_; // Sprite del objeto globo @@ -167,14 +168,33 @@ class Balloon { 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 + // --- Posicionamiento y transformación --- + void shiftColliders(); // Alinea el círculo de colisión con el sprite + void shiftSprite(); // Alinea el sprite en pantalla + void applyBounceEffect(); // Aplica la deformación visual causada por el efecto de rebote + + // --- Animación y sonido --- void setAnimation(); // Establece la animación correspondiente - void playSound(const std::string &name) const; // Reproduce sonido + void playSound(const std::string &name) const; // Reproduce un sonido por nombre + void playBouncingSound(); // Reproduce el sonido de rebote + + // --- Movimiento y física --- + void handleHorizontalMovement(); // Maneja el movimiento horizontal + void handleVerticalMovement(); // Maneja el movimiento vertical + void applyGravity(); // Aplica la gravedad al objeto + + // --- Rebote --- + void enableBounceEffect(); // Activa el efecto de rebote + void disableBounceEffect(); // Detiene el efecto de rebote + void updateBounceEffect(); // Actualiza el estado del rebote + void handleHorizontalBounce(float minX, float maxX); // Maneja el rebote horizontal dentro de límites + + // --- Colisiones --- + bool isOutOfHorizontalBounds(float minX, float maxX) const; // Verifica si está fuera de los límites horizontales + bool shouldCheckTopCollision() const; // Determina si debe comprobarse la colisión superior + void handleTopCollision(); // Maneja la colisión superior + void handleBottomCollision(); // Maneja la colisión inferior + + // --- Lógica de estado --- + void updateState(); // Actualiza los estados del globo }; \ No newline at end of file diff --git a/source/moving_sprite.cpp b/source/moving_sprite.cpp index 92c2db7..206dc6e 100644 --- a/source/moving_sprite.cpp +++ b/source/moving_sprite.cpp @@ -8,8 +8,8 @@ MovingSprite::MovingSprite(std::shared_ptr texture, SDL_FRect pos, Rota x_(pos.x), y_(pos.y), rotate_(rotate), - zoom_w_(zoom_w), - zoom_h_(zoom_h), + horizontal_zoom_(zoom_w), + vertical_zoom_(zoom_h), flip_(flip) {} MovingSprite::MovingSprite(std::shared_ptr texture, SDL_FRect pos) @@ -17,15 +17,15 @@ MovingSprite::MovingSprite(std::shared_ptr texture, SDL_FRect pos) x_(pos.x), y_(pos.y), - zoom_w_(1.0F), - zoom_h_(1.0F), + horizontal_zoom_(1.0F), + vertical_zoom_(1.0F), flip_(SDL_FLIP_NONE) {} MovingSprite::MovingSprite(std::shared_ptr texture) : Sprite(texture), - zoom_w_(1.0F), - zoom_h_(1.0F), + horizontal_zoom_(1.0F), + vertical_zoom_(1.0F), flip_(SDL_FLIP_NONE) { Sprite::clear(); } // Reinicia todas las variables @@ -41,8 +41,8 @@ void MovingSprite::clear() { rotate_ = Rotate(); // Inicializa la estructura - zoom_w_ = 1.0F; // Zoom aplicado a la anchura - zoom_h_ = 1.0F; // Zoom aplicado a la altura + horizontal_zoom_ = 1.0F; // Zoom aplicado a la anchura + vertical_zoom_ = 1.0F; // Zoom aplicado a la altura flip_ = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite @@ -68,7 +68,7 @@ void MovingSprite::update() { } // Muestra el sprite por pantalla -void MovingSprite::render() { texture_->render(pos_.x, pos_.y, &sprite_clip_, zoom_w_, zoom_h_, rotate_.angle, &rotate_.center, flip_); } +void MovingSprite::render() { texture_->render(pos_.x, pos_.y, &sprite_clip_, horizontal_zoom_, vertical_zoom_, rotate_.angle, &rotate_.center, flip_); } // Establece la rotacion void MovingSprite::rotate() { diff --git a/source/moving_sprite.h b/source/moving_sprite.h index 7dd8a05..26ea2c6 100644 --- a/source/moving_sprite.h +++ b/source/moving_sprite.h @@ -1,6 +1,7 @@ #pragma once #include // Para SDL_FlipMode, SDL_FPoint, SDL_FRect + #include // Para max #include // Para shared_ptr @@ -50,8 +51,8 @@ class MovingSprite : public Sprite { // --- Rotación --- [[nodiscard]] auto isRotating() const -> bool { return rotate_.enabled; } - void setZoomW(float value) { zoom_w_ = value; } - void setZoomH(float value) { zoom_h_ = value; } + void setHorizontalZoom(float value) { horizontal_zoom_ = value; } + void setVerticalZoom(float value) { vertical_zoom_ = value; } void setAngle(double value) { rotate_.angle = value; } void setRotatingCenter(SDL_FPoint point) { rotate_.center = point; } void setRotate(bool enable); // Activa o desactiva el efecto de rotación @@ -82,10 +83,10 @@ class MovingSprite : public Sprite { float ay_ = 0.0F; // Aceleración en el eje Y. Variación de la velocidad // --- Efectos visuales --- - Rotate rotate_; // Variables usadas para controlar la rotación del sprite - float zoom_w_; // Zoom aplicado a la anchura - float zoom_h_; // Zoom aplicado a la altura - SDL_FlipMode flip_; // Indica cómo se voltea el sprite + Rotate rotate_; // Variables usadas para controlar la rotación del sprite + float horizontal_zoom_; // Zoom aplicado a la anchura + float vertical_zoom_; // Zoom aplicado a la altura + SDL_FlipMode flip_; // Indica cómo se voltea el sprite // --- Métodos internos --- void updateAngle() { rotate_.angle += rotate_.amount; } // Incrementa el valor del ángulo