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
This commit is contained in:
2025-07-23 18:03:49 +02:00
parent b0564ceccf
commit 5f170ee44e
4 changed files with 166 additions and 119 deletions

View File

@@ -140,80 +140,102 @@ void Balloon::render() {
// Actualiza la posición y estados del globo // Actualiza la posición y estados del globo
void Balloon::move() { void Balloon::move() {
// Comprueba si se puede mover if (isStopped()) {
if (!isStopped()) { return;
// Mueve el globo en horizontal }
x_ += vx_ * speed_;
// Colisión en las partes laterales de la zona de juego handleHorizontalMovement();
const int CLIP = 2; handleVerticalMovement();
const float MIN_X = play_area_.x - CLIP; applyGravity();
const float MAX_X = play_area_.x + play_area_.w - w_ + CLIP; }
if (x_ < MIN_X || x_ > MAX_X) {
if (bouncing_sound_enabled_) { void Balloon::handleHorizontalMovement() {
playSound(bouncing_sound_); x_ += vx_ * speed_;
}
x_ = std::clamp(x_, MIN_X, MAX_X); const int CLIP = 2;
vx_ = -vx_; const float MIN_X = play_area_.x - CLIP;
// Activa el efecto de rebote o invierte la rotación const float MAX_X = play_area_.x + play_area_.w - w_ + CLIP;
if (type_ == BalloonType::POWERBALL) {
sprite_->switchRotate(); if (isOutOfHorizontalBounds(MIN_X, MAX_X)) {
} else { handleHorizontalBounce(MIN_X, MAX_X);
enableBounce(); }
} }
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 void Balloon::applyGravity() {
y_ += vy_ * speed_; /*
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 travel_y_ += speed_;
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();
}
}
// Colisión en la parte inferior de la zona de juego if (travel_y_ >= 1.0F) {
const int MAX_Y = play_area_.y + play_area_.h - h_; travel_y_ -= 1.0F;
if (y_ > MAX_Y) { vy_ += gravity_;
if (bouncing_sound_enabled_) { }
playSound(bouncing_sound_); }
}
y_ = MAX_Y;
vy_ = -default_vy_;
if (type_ != BalloonType::POWERBALL) {
enableBounce();
} else {
setInvulnerable(false);
}
}
/* void Balloon::playBouncingSound() {
if (bouncing_sound_enabled_) {
Para aplicar la gravedad, el diseño original la aplicaba en cada iteración del bucle playSound(bouncing_sound_);
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_;
}
} }
} }
@@ -221,7 +243,7 @@ void Balloon::move() {
void Balloon::update() { void Balloon::update() {
move(); move();
updateState(); updateState();
updateBounce(); updateBounceEffect();
shiftSprite(); shiftSprite();
shiftColliders(); shiftColliders();
sprite_->update(); sprite_->update();
@@ -321,37 +343,41 @@ void Balloon::shiftSprite() {
sprite_->setPosY(y_); sprite_->setPosY(y_);
} }
// Establece el nivel de zoom del sprite // Aplica la deformación visual causada por el efecto de rebote
void Balloon::zoomSprite() { void Balloon::applyBounceEffect() {
sprite_->setZoomW(bouncing_.horizontal_zoom); sprite_->setHorizontalZoom(bounce_effect_.horizontal_zoom);
sprite_->setZoomH(bouncing_.verical_zoom); sprite_->setVerticalZoom(bounce_effect_.verical_zoom);
} }
// Activa el efecto // Activa el efecto
void Balloon::enableBounce() { void Balloon::enableBounceEffect() {
bouncing_.enabled = true; // Los globos pequeños no tienen efecto de rebote
bouncing_.reset(); if (size_ == BalloonSize::SIZE1) {
zoomSprite(); return;
}
bounce_effect_.enabled = true;
bounce_effect_.reset();
applyBounceEffect();
} }
// Detiene el efecto // Detiene el efecto
void Balloon::disableBounce() { void Balloon::disableBounceEffect() {
bouncing_.enabled = false; bounce_effect_.enabled = false;
bouncing_.reset(); bounce_effect_.reset();
zoomSprite(); applyBounceEffect();
} }
// Aplica el efecto // Aplica el efecto
void Balloon::updateBounce() { void Balloon::updateBounceEffect() {
if (bouncing_.enabled) { if (bounce_effect_.enabled) {
const int INDEX = bouncing_.counter / bouncing_.speed; const int INDEX = bounce_effect_.counter / bounce_effect_.speed;
bouncing_.horizontal_zoom = bouncing_.horizontal_zoom_values[INDEX]; bounce_effect_.horizontal_zoom = bounce_effect_.horizontal_zoom_values[INDEX];
bouncing_.verical_zoom = bouncing_.vertical_zoom_values[INDEX]; bounce_effect_.verical_zoom = bounce_effect_.vertical_zoom_values[INDEX];
zoomSprite(); applyBounceEffect();
if (++bouncing_.counter / bouncing_.speed >= MAX_BOUNCE) { if (++bounce_effect_.counter / bounce_effect_.speed >= MAX_BOUNCE) {
disableBounce(); disableBounceEffect();
} }
} }
} }

View File

@@ -1,10 +1,11 @@
#pragma once #pragma once
#include <SDL3/SDL.h> // Para Uint8, Uint16, SDL_FRect, Uint32 #include <SDL3/SDL.h> // Para Uint8, Uint16, SDL_FRect, Uint32
#include <array> // Para array
#include <memory> // Para allocator, shared_ptr, unique_ptr #include <array> // Para array
#include <string> // Para basic_string, string #include <memory> // Para allocator, shared_ptr, unique_ptr
#include <vector> // Para vector #include <string> // Para basic_string, string
#include <vector> // Para vector
#include "animated_sprite.h" // Para AnimatedSprite #include "animated_sprite.h" // Para AnimatedSprite
#include "utils.h" // Para Circle #include "utils.h" // Para Circle
@@ -129,7 +130,7 @@ class Balloon {
desp_x = 0.0F; desp_x = 0.0F;
desp_y = 0.0F; desp_y = 0.0F;
} }
} bouncing_; } bounce_effect_;
// --- Objetos y punteros --- // --- Objetos y punteros ---
std::unique_ptr<AnimatedSprite> sprite_; // Sprite del objeto globo std::unique_ptr<AnimatedSprite> sprite_; // Sprite del objeto globo
@@ -167,14 +168,33 @@ class Balloon {
bool poping_sound_enabled_ = true; // Si debe sonar el globo al explotar bool poping_sound_enabled_ = true; // Si debe sonar el globo al explotar
bool sound_enabled_ = true; // Indica si los globos deben hacer algun sonido bool sound_enabled_ = true; // Indica si los globos deben hacer algun sonido
// --- Métodos internos --- // --- Posicionamiento y transformación ---
void shiftColliders(); // Alinea el círculo de colisión void shiftColliders(); // Alinea el círculo de colisión con el sprite
void shiftSprite(); // Alinea el sprite void shiftSprite(); // Alinea el sprite en pantalla
void zoomSprite(); // Establece el nivel de zoom del sprite void applyBounceEffect(); // Aplica la deformación visual causada por el efecto de rebote
void enableBounce(); // Activa el efecto de rebote
void disableBounce(); // Detiene el efecto de rebote // --- Animación y sonido ---
void updateBounce(); // Aplica el efecto de rebote
void updateState(); // Actualiza los estados del globo
void setAnimation(); // Establece la animación correspondiente 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
}; };

View File

@@ -8,8 +8,8 @@ MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_FRect pos, Rota
x_(pos.x), x_(pos.x),
y_(pos.y), y_(pos.y),
rotate_(rotate), rotate_(rotate),
zoom_w_(zoom_w), horizontal_zoom_(zoom_w),
zoom_h_(zoom_h), vertical_zoom_(zoom_h),
flip_(flip) {} flip_(flip) {}
MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_FRect pos) MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_FRect pos)
@@ -17,15 +17,15 @@ MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_FRect pos)
x_(pos.x), x_(pos.x),
y_(pos.y), y_(pos.y),
zoom_w_(1.0F), horizontal_zoom_(1.0F),
zoom_h_(1.0F), vertical_zoom_(1.0F),
flip_(SDL_FLIP_NONE) {} flip_(SDL_FLIP_NONE) {}
MovingSprite::MovingSprite(std::shared_ptr<Texture> texture) MovingSprite::MovingSprite(std::shared_ptr<Texture> texture)
: Sprite(texture), : Sprite(texture),
zoom_w_(1.0F), horizontal_zoom_(1.0F),
zoom_h_(1.0F), vertical_zoom_(1.0F),
flip_(SDL_FLIP_NONE) { Sprite::clear(); } flip_(SDL_FLIP_NONE) { Sprite::clear(); }
// Reinicia todas las variables // Reinicia todas las variables
@@ -41,8 +41,8 @@ void MovingSprite::clear() {
rotate_ = Rotate(); // Inicializa la estructura rotate_ = Rotate(); // Inicializa la estructura
zoom_w_ = 1.0F; // Zoom aplicado a la anchura horizontal_zoom_ = 1.0F; // Zoom aplicado a la anchura
zoom_h_ = 1.0F; // Zoom aplicado a la altura vertical_zoom_ = 1.0F; // Zoom aplicado a la altura
flip_ = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite flip_ = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite
@@ -68,7 +68,7 @@ void MovingSprite::update() {
} }
// Muestra el sprite por pantalla // 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 // Establece la rotacion
void MovingSprite::rotate() { void MovingSprite::rotate() {

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <SDL3/SDL.h> // Para SDL_FlipMode, SDL_FPoint, SDL_FRect #include <SDL3/SDL.h> // Para SDL_FlipMode, SDL_FPoint, SDL_FRect
#include <algorithm> // Para max #include <algorithm> // Para max
#include <memory> // Para shared_ptr #include <memory> // Para shared_ptr
@@ -50,8 +51,8 @@ class MovingSprite : public Sprite {
// --- Rotación --- // --- Rotación ---
[[nodiscard]] auto isRotating() const -> bool { return rotate_.enabled; } [[nodiscard]] auto isRotating() const -> bool { return rotate_.enabled; }
void setZoomW(float value) { zoom_w_ = value; } void setHorizontalZoom(float value) { horizontal_zoom_ = value; }
void setZoomH(float value) { zoom_h_ = value; } void setVerticalZoom(float value) { vertical_zoom_ = value; }
void setAngle(double value) { rotate_.angle = value; } void setAngle(double value) { rotate_.angle = value; }
void setRotatingCenter(SDL_FPoint point) { rotate_.center = point; } void setRotatingCenter(SDL_FPoint point) { rotate_.center = point; }
void setRotate(bool enable); // Activa o desactiva el efecto de rotación 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 float ay_ = 0.0F; // Aceleración en el eje Y. Variación de la velocidad
// --- Efectos visuales --- // --- Efectos visuales ---
Rotate rotate_; // Variables usadas para controlar la rotación del sprite Rotate rotate_; // Variables usadas para controlar la rotación del sprite
float zoom_w_; // Zoom aplicado a la anchura float horizontal_zoom_; // Zoom aplicado a la anchura
float zoom_h_; // Zoom aplicado a la altura float vertical_zoom_; // Zoom aplicado a la altura
SDL_FlipMode flip_; // Indica cómo se voltea el sprite SDL_FlipMode flip_; // Indica cómo se voltea el sprite
// --- Métodos internos --- // --- Métodos internos ---
void updateAngle() { rotate_.angle += rotate_.amount; } // Incrementa el valor del ángulo void updateAngle() { rotate_.angle += rotate_.amount; } // Incrementa el valor del ángulo