Revisada la classe Balloon

This commit is contained in:
2024-10-26 18:08:04 +02:00
parent f750997b34
commit 6235d0b684
3 changed files with 218 additions and 344 deletions

View File

@@ -1,5 +1,6 @@
#include "balloon.h" #include "balloon.h"
#include <cmath> // para abs #include <cmath> // para abs
#include <algorithm> // para clamp
#include "animated_sprite.h" // para SpriteAnimated #include "animated_sprite.h" // para SpriteAnimated
#include "moving_sprite.h" // para MovingSprite #include "moving_sprite.h" // para MovingSprite
#include "param.h" // para param #include "param.h" // para param
@@ -9,9 +10,9 @@
// Constructor // Constructor
Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel_x, float speed, Uint16 creation_timer, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation) Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel_x, float speed, Uint16 creation_timer, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation)
: sprite_(std::make_unique<AnimatedSprite>(texture, animation)), : sprite_(std::make_unique<AnimatedSprite>(texture, animation)),
pos_x_(x), x_(x),
pos_y_(y), y_(y),
vel_x_(vel_x), vx_(vel_x),
being_created_(creation_timer > 0), being_created_(creation_timer > 0),
invulnerable_(creation_timer > 0), invulnerable_(creation_timer > 0),
creation_counter_(creation_timer), creation_counter_(creation_timer),
@@ -24,13 +25,13 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel
{ {
case BalloonType::BALLOON: case BalloonType::BALLOON:
{ {
vel_y_ = 0; vy_ = 0;
max_vel_y_ = 3.0f; max_vy_ = 3.0f;
const int size = static_cast<int>(size_); const int size = static_cast<int>(size_);
gravity_ = param.balloon.at(size).grav; gravity_ = param.balloon.at(size).grav;
default_vel_y_ = param.balloon.at(size).vel; default_vy_ = param.balloon.at(size).vel;
height_ = width_ = BALLOON_SIZE[size]; h_ = w_ = BALLOON_SIZE[size];
power_ = BALLOON_POWER[size]; power_ = BALLOON_POWER[size];
menace_ = BALLOON_MENACE[size]; menace_ = BALLOON_MENACE[size];
score_ = BALLOON_SCORE[size]; score_ = BALLOON_SCORE[size];
@@ -40,11 +41,11 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel
case BalloonType::FLOATER: case BalloonType::FLOATER:
{ {
default_vel_y_ = max_vel_y_ = vel_y_ = fabs(vel_x_ * 2.0f); default_vy_ = max_vy_ = vy_ = fabs(vx_ * 2.0f);
gravity_ = 0.00f; gravity_ = 0.00f;
const int size = static_cast<int>(size_); const int size = static_cast<int>(size_);
height_ = width_ = BALLOON_SIZE[size]; h_ = w_ = BALLOON_SIZE[size];
power_ = BALLOON_POWER[size]; power_ = BALLOON_POWER[size];
menace_ = BALLOON_MENACE[size]; menace_ = BALLOON_MENACE[size];
score_ = BALLOON_SCORE[size]; score_ = BALLOON_SCORE[size];
@@ -55,20 +56,17 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel
case BalloonType::POWERBALL: case BalloonType::POWERBALL:
{ {
const int size = 3; const int size = 3;
// Alto y ancho del objeto h_ = w_ = BALLOON_SIZE[size];
height_ = width_ = BALLOON_SIZE[size];
power_ = score_ = menace_ = 0; power_ = score_ = menace_ = 0;
// Inicializa los valores de velocidad y gravedad vy_ = 0;
vel_y_ = 0; max_vy_ = 3.0f;
max_vel_y_ = 3.0f;
gravity_ = param.balloon.at(size).grav; gravity_ = param.balloon.at(size).grav;
default_vel_y_ = param.balloon.at(size).vel; default_vy_ = param.balloon.at(size).vel;
// Añade rotación al sprite_
sprite_->disableRotate(); sprite_->disableRotate();
sprite_->setRotateSpeed(0); sprite_->setRotateSpeed(0);
sprite_->setRotateAmount(vel_x_ > 0.0f ? 2.0 : -2.0); sprite_->setRotateAmount(vx_ > 0.0f ? 2.0 : -2.0);
break; break;
} }
@@ -77,82 +75,54 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel
break; break;
} }
// Valores para el efecto de rebote
bouncing_.enabled = false;
bouncing_.counter = 0;
bouncing_.speed = 2;
bouncing_.zoomW = 1.0f;
bouncing_.zoomH = 1.0f;
bouncing_.despX = 0.0f;
bouncing_.despY = 0.0f;
bouncing_.w = {1.10f, 1.05f, 1.00f, 0.95f, 0.90f, 0.95f, 1.00f, 1.02f, 1.05f, 1.02f};
bouncing_.h = {0.90f, 0.95f, 1.00f, 1.05f, 1.10f, 1.05f, 1.00f, 0.98f, 0.95f, 0.98f};
// Configura el sprite // Configura el sprite
sprite_->setPos({static_cast<int>(pos_x_), static_cast<int>(pos_y_), width_, height_}); sprite_->setWidth(w_);
sprite_->setHeight(h_);
shiftSprite();
// Alinea el circulo de colisión con el objeto // Alinea el circulo de colisión con el objeto
collider_.r = width_ / 2; collider_.r = w_ / 2;
shiftColliders(); shiftColliders();
} }
// Centra el globo en la posición X // Centra el globo en la posición X
void Balloon::allignTo(int x) void Balloon::alignTo(int x)
{ {
pos_x_ = float(x - (width_ / 2)); x_ = static_cast<float>(x - (w_ / 2));
const int min_x = param.game.play_area.rect.x;
if (pos_x_ < param.game.play_area.rect.x) const int max_x = param.game.play_area.rect.w - w_;
{ x_ = std::clamp(x_, static_cast<float>(min_x), static_cast<float>(max_x));
pos_x_ = param.game.play_area.rect.x + 1;
}
else if ((pos_x_ + width_) > param.game.play_area.rect.w)
{
pos_x_ = float(param.game.play_area.rect.w - width_ - 1);
}
// Posición X,Y del sprite_
sprite_->setPosX(getPosX());
sprite_->setPosY(getPosY());
// Alinea el circulo de colisión con el objeto
shiftColliders();
} }
// Pinta el globo en la pantalla // Pinta el globo en la pantalla
void Balloon::render() void Balloon::render()
{ {
if (visible_ && enabled_) if (isBeingCreated())
{
// Aplica alpha blending
sprite_->getTexture()->setAlpha(255 - (int)((float)creation_counter_ * (255.0f / (float)creation_counter_ini_)));
sprite_->render();
sprite_->getTexture()->setAlpha(255);
}
else
{ {
if (bouncing_.enabled) if (bouncing_.enabled)
{ {
if (type_ != BalloonType::POWERBALL) // Aplica efecto de bouncing
{ sprite_->setPos(x_ + bouncing_.despX, y_ + bouncing_.despY);
// Aplica desplazamiento para el zoom
sprite_->setPosX(getPosX() + bouncing_.despX);
sprite_->setPosY(getPosY() + bouncing_.despY);
sprite_->render();
sprite_->setPosX(getPosX() - bouncing_.despX);
sprite_->setPosY(getPosY() - bouncing_.despY);
}
}
else if (isBeingCreated())
{
// Aplica alpha blending
sprite_->getTexture()->setAlpha(255 - (int)((float)creation_counter_ * (255.0f / (float)creation_counter_ini_)));
sprite_->render(); sprite_->render();
sprite_->getTexture()->setAlpha(255); sprite_->setPos(x_ - bouncing_.despX, y_ - bouncing_.despY);
} }
else else
{
sprite_->render(); sprite_->render();
} }
if (type_ == BalloonType::POWERBALL && !isBeingCreated()) // Añade la máscara del borde a la PowerBall
{ if (type_ == BalloonType::POWERBALL && !isBeingCreated())
auto sp = std::make_unique<Sprite>(sprite_->getTexture(), sprite_->getPosition()); {
sp->setSpriteClip(BALLOON_SIZE[3], 0, BALLOON_SIZE[3], BALLOON_SIZE[3]); auto sp = std::make_unique<Sprite>(sprite_->getTexture(), sprite_->getPosition());
sp->render(); sp->setSpriteClip(BALLOON_SIZE[3], 0, BALLOON_SIZE[3], BALLOON_SIZE[3]);
} sp->render();
} }
} }
@@ -162,61 +132,45 @@ void Balloon::move()
// Comprueba si se puede mover // Comprueba si se puede mover
if (!isStopped()) if (!isStopped())
{ {
// Lo mueve a izquierda o derecha // Mueve el globo en horizontal
pos_x_ += (vel_x_ * speed_); x_ += vx_ * speed_;
// Si queda fuera de pantalla, corregimos su posición y cambiamos su sentido // Colisión en las partes laterales de la zona de juego
if ((pos_x_ < param.game.play_area.rect.x) || (pos_x_ + width_ > param.game.play_area.rect.w)) const int clip = 2;
const float min_x = param.game.play_area.rect.x - clip;
const float max_x = param.game.play_area.rect.w - w_ + clip;
if (x_ < min_x || x_ > max_x)
{ {
// Corrige posición x_ = std::clamp(x_, min_x, max_x);
pos_x_ -= (vel_x_ * speed_); vx_ = -vx_;
// Activa el efecto de rebote o invierte la rotación
// Invierte sentido if (type_ == BalloonType::POWERBALL)
vel_x_ = -vel_x_; sprite_->switchRotate();
else
// Invierte la rotación enableBounce();
sprite_->switchRotate();
// Activa el efecto de rebote
if (type_ != BalloonType::POWERBALL)
{
bounceStart();
}
} }
// Mueve el globo hacia arriba o hacia abajo // Mueve el globo en vertical
pos_y_ += (vel_y_ * speed_); y_ += vy_ * speed_;
// Si se sale por arriba // Colisión en la parte superior de la zona de juego
if (pos_y_ < param.game.play_area.rect.y) const int min_y = param.game.play_area.rect.y;
if (y_ < min_y)
{ {
// Corrige y_ = min_y;
pos_y_ = param.game.play_area.rect.y; vy_ = -vy_;
// Invierte sentido
vel_y_ = -vel_y_;
// Activa el efecto de rebote
if (type_ != BalloonType::POWERBALL) if (type_ != BalloonType::POWERBALL)
{ enableBounce();
bounceStart();
}
} }
// Si el globo se sale por la parte inferior // Colisión en la parte inferior de la zona de juego
if (pos_y_ + height_ > param.game.play_area.rect.h) const int max_y = param.game.play_area.rect.h - h_;
if (y_ > max_y)
{ {
// Corrige y_ = max_y;
pos_y_ = param.game.play_area.rect.h - height_; vy_ = -default_vy_;
// Invierte colocando una velocidad por defecto
vel_y_ = -default_vel_y_;
// Activa el efecto de rebote
if (type_ != BalloonType::POWERBALL) if (type_ != BalloonType::POWERBALL)
{ enableBounce();
bounceStart();
}
} }
/* /*
@@ -238,46 +192,15 @@ void Balloon::move()
travel_y_ -= 1.0f; travel_y_ -= 1.0f;
// Aplica la gravedad al objeto sin pasarse de una velocidad máxima // Aplica la gravedad al objeto sin pasarse de una velocidad máxima
vel_y_ += gravity_; vy_ += gravity_;
} }
// Actualiza la posición del sprite_
sprite_->setPosX(getPosX());
sprite_->setPosY(getPosY());
} }
} }
// Deshabilita el globo y pone a cero todos los valores // Deshabilita el globo y pone a cero todos los valores
void Balloon::disable() void Balloon::disable()
{ {
being_created_ = false;
blinking_ = false;
collider_.r = 0;
collider_.x = 0;
collider_.y = 0;
counter_ = 0;
creation_counter_ = 0;
creation_counter_ini_ = 0;
default_vel_y_ = 0.0f;
enabled_ = false; enabled_ = false;
gravity_ = 0.0f;
height_ = 0;
invulnerable_ = false;
max_vel_y_ = 0.0f;
menace_ = 0;
pos_x_ = 0.0f;
pos_y_ = 0.0f;
power_ = 0;
score_ = 0;
speed_ = 0;
stopped_ = false;
stopped_counter_ = 0;
travel_y_ = 0;
vel_x_ = 0.0f;
vel_y_ = 0.0f;
visible_ = false;
width_ = 0;
sprite_->clear();
} }
// Explosiona el globo // Explosiona el globo
@@ -289,16 +212,14 @@ void Balloon::pop()
// Actualiza al globo a su posicion, animación y controla los contadores // Actualiza al globo a su posicion, animación y controla los contadores
void Balloon::update() void Balloon::update()
{ {
if (enabled_) move();
{ updateAnimation();
sprite_->update(); updateState();
move(); updateBounce();
updateAnimation(); shiftSprite();
shiftColliders(); shiftColliders();
updateState(); sprite_->update();
updateBounce(); ++counter_;
++counter_;
}
} }
// Actualiza los estados del globo // Actualiza los estados del globo
@@ -311,70 +232,54 @@ void Balloon::updateState()
setStop(true); setStop(true);
setInvulnerable(true); setInvulnerable(true);
// Todavia tiene tiempo en el contador
if (creation_counter_ > 0) if (creation_counter_ > 0)
{ {
// Desplaza lentamente el globo hacia abajo y hacia un lado // Desplaza lentamente el globo hacia abajo y hacia un lado
if (creation_counter_ % 10 == 0) if (creation_counter_ % 10 == 0)
{ {
pos_y_++; y_++;
pos_x_ += vel_x_; x_ += vx_;
// Comprueba no se salga por los laterales // Comprueba no se salga por los laterales
if ((pos_x_ < param.game.play_area.rect.x) || (pos_x_ > (param.game.play_area.rect.w - width_))) const int min_x = param.game.play_area.rect.x;
const int max_x = param.game.play_area.rect.w - w_;
if (x_ < min_x || x_ > max_x)
{ {
// Corrige y cambia el sentido de la velocidad // Corrige y cambia el sentido de la velocidad
pos_x_ -= vel_x_; x_ -= vx_;
vel_x_ = -vel_x_; vx_ = -vx_;
} }
// Actualiza la posición del sprite_
sprite_->setPosX(getPosX());
sprite_->setPosY(getPosY());
// Actualiza la posición del circulo de colisión
shiftColliders();
} }
--creation_counter_;
creation_counter_--;
} }
// El contador ha llegado a cero
else else
{ {
setBeingCreated(false); // El contador ha llegado a cero
being_created_ = false;
// visible_ = true;
setStop(false); setStop(false);
setVisible(true);
setInvulnerable(false); setInvulnerable(false);
if (type_ == BalloonType::POWERBALL) if (type_ == BalloonType::POWERBALL)
{
sprite_->enableRotate(); sprite_->enableRotate();
}
} }
} }
// Solo comprueba el estado detenido cuando no se está creando
else if (isStopped()) else if (isStopped())
{ {
// Si es una powerball deja de rodar // Solo comprueba el estado detenido cuando no se está creando
if (type_ == BalloonType::POWERBALL) if (type_ == BalloonType::POWERBALL)
{
sprite_->disableRotate(); sprite_->disableRotate();
}
// Reduce el contador // Reduce el contador
if (stopped_counter_ > 0) if (stopped_counter_ > 0)
{ --stopped_counter_;
stopped_counter_--;
}
// Si el contador ha llegado a cero
else else
{ // Quitarles el estado "detenido" {
// Si el contador ha llegado a cero
setStop(false); setStop(false);
// Si es una powerball vuelve a rodar
if (type_ == BalloonType::POWERBALL) if (type_ == BalloonType::POWERBALL)
{
sprite_->enableRotate(); sprite_->enableRotate();
}
} }
} }
} }
@@ -382,23 +287,27 @@ void Balloon::updateState()
// Establece la animación correspondiente al estado // Establece la animación correspondiente al estado
void Balloon::updateAnimation() void Balloon::updateAnimation()
{ {
std::string creating_animation = "blue"; std::string creating_animation;
std::string normal_animation = "orange"; std::string normal_animation;
if (type_ == BalloonType::POWERBALL) switch (type_)
{ {
case BalloonType::POWERBALL:
creating_animation = "powerball"; creating_animation = "powerball";
normal_animation = "powerball"; normal_animation = "powerball";
} break;
else if (type_ == BalloonType::FLOATER) case BalloonType::FLOATER:
{
creating_animation = "red"; creating_animation = "red";
normal_animation = "green"; normal_animation = "green";
break;
default:
creating_animation = "blue";
normal_animation = "orange";
break;
} }
// Establece el frame de animación // Establece el frame de animación
sprite_->setCurrentAnimation(isBeingCreated() ? creating_animation : normal_animation); sprite_->setCurrentAnimation(isBeingCreated() ? creating_animation : normal_animation);
sprite_->update();
} }
// Comprueba si el globo está habilitado // Comprueba si el globo está habilitado
@@ -410,37 +319,31 @@ bool Balloon::isEnabled() const
// Obtiene del valor de la variable // Obtiene del valor de la variable
float Balloon::getPosX() const float Balloon::getPosX() const
{ {
return pos_x_; return x_;
} }
// Obtiene del valor de la variable // Obtiene del valor de la variable
float Balloon::getPosY() const float Balloon::getPosY() const
{ {
return pos_y_; return y_;
}
// Obtiene del valor de la variable
float Balloon::getVelY() const
{
return vel_y_;
} }
// Obtiene del valor de la variable // Obtiene del valor de la variable
int Balloon::getWidth() const int Balloon::getWidth() const
{ {
return width_; return w_;
} }
// Obtiene del valor de la variable // Obtiene del valor de la variable
int Balloon::getHeight() const int Balloon::getHeight() const
{ {
return height_; return h_;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Balloon::setVelY(float vel_y) void Balloon::setVelY(float vel_y)
{ {
vel_y_ = vel_y; vy_ = vel_y;
} }
// Establece el valor de la variable // Establece el valor de la variable
@@ -485,18 +388,6 @@ bool Balloon::isBlinking() const
return blinking_; return blinking_;
} }
// Establece el valor de la variable
void Balloon::setVisible(bool value)
{
visible_ = value;
}
// Obtiene del valor de la variable
bool Balloon::isVisible() const
{
return visible_;
}
// Establece el valor de la variable // Establece el valor de la variable
void Balloon::setInvulnerable(bool value) void Balloon::setInvulnerable(bool value)
{ {
@@ -509,12 +400,6 @@ bool Balloon::isInvulnerable() const
return invulnerable_; return invulnerable_;
} }
// Establece el valor de la variable
void Balloon::setBeingCreated(bool value)
{
being_created_ = value;
}
// Obtiene del valor de la variable // Obtiene del valor de la variable
bool Balloon::isBeingCreated() const bool Balloon::isBeingCreated() const
{ {
@@ -548,8 +433,22 @@ Circle &Balloon::getCollider()
// Alinea el circulo de colisión con la posición del objeto globo // Alinea el circulo de colisión con la posición del objeto globo
void Balloon::shiftColliders() void Balloon::shiftColliders()
{ {
collider_.x = Uint16(pos_x_ + collider_.r); collider_.x = static_cast<int>(x_) + collider_.r;
collider_.y = pos_y_ + collider_.r; collider_.y = static_cast<int>(y_) + collider_.r;
}
// Alinea el sprite con la posición del objeto globo
void Balloon::shiftSprite()
{
sprite_->setPosX(x_);
sprite_->setPosY(y_);
}
// Establece el nivel de zoom del sprite
void Balloon::zoomSprite()
{
sprite_->setZoomW(bouncing_.zoomW);
sprite_->setZoomH(bouncing_.zoomH);
} }
// Obtiene le valor de la variable // Obtiene le valor de la variable
@@ -564,44 +463,39 @@ Uint8 Balloon::getPower() const
return power_; return power_;
} }
void Balloon::bounceStart() // Activa el efecto
void Balloon::enableBounce()
{ {
bouncing_.enabled = true; bouncing_.enabled = true;
bouncing_.zoomW = 1; bouncing_.reset();
bouncing_.zoomH = 1; zoomSprite();
sprite_->setZoomW(bouncing_.zoomW);
sprite_->setZoomH(bouncing_.zoomH);
bouncing_.despX = 0;
bouncing_.despY = 0;
} }
void Balloon::bounceStop() // Detiene el efecto
void Balloon::disableBounce()
{ {
bouncing_.enabled = false; bouncing_.enabled = false;
bouncing_.counter = 0; bouncing_.reset();
bouncing_.zoomW = 1.0f; zoomSprite();
bouncing_.zoomH = 1.0f;
sprite_->setZoomW(bouncing_.zoomW);
sprite_->setZoomH(bouncing_.zoomH);
bouncing_.despX = 0.0f;
bouncing_.despY = 0.0f;
} }
// Aplica el efecto
void Balloon::updateBounce() void Balloon::updateBounce()
{ {
if (bouncing_.enabled) if (bouncing_.enabled)
{ {
bouncing_.zoomW = bouncing_.w[bouncing_.counter / bouncing_.speed]; const int index = bouncing_.counter / bouncing_.speed;
bouncing_.zoomH = bouncing_.h[bouncing_.counter / bouncing_.speed]; bouncing_.zoomW = bouncing_.w[index];
sprite_->setZoomW(bouncing_.zoomW); bouncing_.zoomH = bouncing_.h[index];
sprite_->setZoomH(bouncing_.zoomH);
bouncing_.despX = (sprite_->getSpriteClip().w - (sprite_->getSpriteClip().w * bouncing_.zoomW)); zoomSprite();
bouncing_.despY = (sprite_->getSpriteClip().h - (sprite_->getSpriteClip().h * bouncing_.zoomH));
++bouncing_.counter; const auto spriteClip = sprite_->getSpriteClip();
if ((bouncing_.counter / bouncing_.speed) > (MAX_BOUNCE - 1)) bouncing_.despX = spriteClip.w * (1.0f - bouncing_.zoomW);
{ bouncing_.despY = spriteClip.h * (1.0f - bouncing_.zoomH);
bounceStop();
} if (++bouncing_.counter / bouncing_.speed >= MAX_BOUNCE)
disableBounce();
} }
} }

View File

@@ -13,10 +13,10 @@ class Texture;
constexpr int MAX_BOUNCE = 10; constexpr int MAX_BOUNCE = 10;
// Puntos de globo // Puntos de globo
constexpr int BALLOON_SCORE[4] = {50, 100, 200, 400}; constexpr int BALLOON_SCORE[] = {50, 100, 200, 400};
constexpr int BALLOON_POWER[4] = {1, 3, 7, 15}; constexpr int BALLOON_POWER[] = {1, 3, 7, 15};
constexpr int BALLOON_MENACE[4] = {1, 2, 4, 8}; constexpr int BALLOON_MENACE[] = {1, 2, 4, 8};
constexpr int BALLOON_SIZE[4] = {10, 16, 26, 46}; constexpr int BALLOON_SIZE[] = {10, 16, 26, 46};
// Tamaños de globo // Tamaños de globo
enum class BalloonSize : Uint8 enum class BalloonSize : Uint8
@@ -45,11 +45,7 @@ constexpr int BALLOON_POP_ANIMATION = 1;
constexpr int BALLOON_BORN_ANIMATION = 2; constexpr int BALLOON_BORN_ANIMATION = 2;
// Velocidades a las que se mueven los globos // Velocidades a las que se mueven los globos
constexpr float BALLOON_SPEED_1 = 0.60f; constexpr float BALLOON_SPEED[] = {0.60f, 0.70f, 0.80f, 0.90f, 1.00f};
constexpr float BALLOON_SPEED_2 = 0.70f;
constexpr float BALLOON_SPEED_3 = 0.80f;
constexpr float BALLOON_SPEED_4 = 0.90f;
constexpr float BALLOON_SPEED_5 = 1.00f;
// PowerBall // PowerBall
constexpr int POWERBALL_SCREENPOWER_MINIMUM = 10; constexpr int POWERBALL_SCREENPOWER_MINIMUM = 10;
@@ -59,39 +55,52 @@ constexpr int POWERBALL_COUNTER = 8;
class Balloon class Balloon
{ {
private: private:
// Estructura para las variables para el efecto de los rebotes // Estructura para el efecto de los rebotes en los globos
struct Bouncing struct Bouncing
{ {
bool enabled; // Si el efecto está activo bool enabled = false; // Si el efecto está activo
Uint8 counter; // Countador para el efecto Uint8 counter = 0; // Contador para el efecto
Uint8 speed; // Velocidad a la que transcurre el efecto Uint8 speed = 2; // Velocidad a la que transcurre el efecto
float zoomW; // Zoom aplicado a la anchura float zoomW = 1.0f; // Zoom aplicado a la anchura
float zoomH; // Zoom aplicado a la altura float zoomH = 1.0f; // Zoom aplicado a la altura
float despX; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom float despX = 0.0f; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom
float despY; // Desplazamiento de pixeles en el eje Y 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
std::vector<float> w; // Vector con los valores de zoom para el ancho del globo
std::vector<float> h; // Vector con los valores de zoom para el alto del globo 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 // Objetos y punteros
std::unique_ptr<AnimatedSprite> sprite_; // Sprite del objeto globo std::unique_ptr<AnimatedSprite> sprite_; // Sprite del objeto globo
// Variables // Variables
float pos_x_; // Posición en el eje X float x_; // Posición en el eje X
float pos_y_; // Posición en el eje Y float y_; // Posición en el eje Y
Uint8 width_; // Ancho Uint8 w_; // Ancho
Uint8 height_; // Alto Uint8 h_; // Alto
float vel_x_; // Velocidad en el eje X. Cantidad de pixeles a desplazarse float vx_; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
float vel_y_; // Velocidad en el eje Y. 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 gravity_; // Aceleración en el eje Y. Modifica la velocidad
float default_vel_y_; // Velocidad inicial que tienen al rebotar contra el suelo float default_vy_; // Velocidad inicial que tienen al rebotar contra el suelo
float max_vel_y_; // Máxima velocidad que puede alcanzar el objeto en el eje Y 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 being_created_; // Indica si el globo se está creando
bool blinking_ = false; // Indica si el globo está intermitente bool blinking_ = false; // Indica si el globo está intermitente
bool enabled_ = true; // Indica si el globo esta activo bool enabled_ = true; // Indica si el globo esta activo
bool invulnerable_; // Indica si el globo es invulnerable bool invulnerable_; // Indica si el globo es invulnerable
bool stopped_ = true; // Indica si el globo está parado bool stopped_ = true; // Indica si el globo está parado
bool visible_ = true; // Indica si el globo es visible
Circle collider_; // Circulo de colisión del objeto Circle collider_; // Circulo de colisión del objeto
Uint16 creation_counter_; // Temporizador para controlar el estado "creandose" Uint16 creation_counter_; // Temporizador para controlar el estado "creandose"
Uint16 creation_counter_ini_; // Valor inicial para el temporizador para controlar el estado "creandose" Uint16 creation_counter_ini_; // Valor inicial para el temporizador para controlar el estado "creandose"
@@ -104,16 +113,21 @@ private:
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 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 float speed_; // Velocidad a la que se mueven los globos
Uint8 power_; // Cantidad de poder que alberga el globo Uint8 power_; // Cantidad de poder que alberga el globo
Bouncing bouncing_; // Contiene las variables para el efecto de rebote
// Alinea el circulo de colisión con la posición del objeto globo // Alinea el circulo de colisión con la posición del objeto globo
void shiftColliders(); 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 // Activa el efecto
void bounceStart(); void enableBounce();
// Detiene el efecto // Detiene el efecto
void bounceStop(); void disableBounce();
// Aplica el efecto // Aplica el efecto
void updateBounce(); void updateBounce();
@@ -124,9 +138,6 @@ private:
// Establece la animación correspondiente // Establece la animación correspondiente
void updateAnimation(); void updateAnimation();
// Establece el valor de la variable
void setBeingCreated(bool value);
public: public:
// Constructor // Constructor
Balloon(float x, float y, BalloonType type, BalloonSize size, float vel_x, float speed, Uint16 creation_timer, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation); Balloon(float x, float y, BalloonType type, BalloonSize size, float vel_x, float speed, Uint16 creation_timer, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation);
@@ -135,7 +146,7 @@ public:
~Balloon() = default; ~Balloon() = default;
// Centra el globo en la posición X // Centra el globo en la posición X
void allignTo(int x); void alignTo(int x);
// Pinta el globo en la pantalla // Pinta el globo en la pantalla
void render(); void render();
@@ -161,9 +172,6 @@ public:
// Obtiene del valor de la variable // Obtiene del valor de la variable
float getPosY() const; float getPosY() const;
// Obtiene del valor de la variable
float getVelY() const;
// Obtiene del valor de la variable // Obtiene del valor de la variable
int getWidth() const; int getWidth() const;
@@ -194,12 +202,6 @@ public:
// Obtiene del valor de la variable // Obtiene del valor de la variable
bool isBlinking() const; bool isBlinking() const;
// Establece el valor de la variable
void setVisible(bool value);
// Obtiene del valor de la variable
bool isVisible() const;
// Establece el valor de la variable // Establece el valor de la variable
void setInvulnerable(bool value); void setInvulnerable(bool value);

View File

@@ -230,27 +230,22 @@ void Game::deployBalloonFormation()
power_ball_counter_ = (power_ball_counter_ > 0) ? (power_ball_counter_ - 1) : 0; power_ball_counter_ = (power_ball_counter_ > 0) ? (power_ball_counter_ - 1) : 0;
// Elige una formación enemiga la azar // Elige una formación enemiga la azar
auto set = rand() % 10; auto formation = rand() % 10;
// Evita repetir la ultima formación enemiga desplegada // Evita repetir la ultima formación enemiga desplegada
if (set == last_balloon_deploy_) if (formation == last_balloon_deploy_)
{ {
++set %= 10; ++formation %= 10;
} }
last_balloon_deploy_ = set; last_balloon_deploy_ = formation;
const Stage stage = balloon_formations_->getStage(current_stage_); const auto set = balloon_formations_->getStage(0).balloon_pool.set[formation];
const auto numEnemies = stage.balloon_pool.set[set].number_of_balloons; const auto numEnemies = set.number_of_balloons;
for (int i = 0; i < numEnemies; ++i) for (int i = 0; i < numEnemies; ++i)
{ {
createBalloon(stage.balloon_pool.set[set].init[i].x, auto p = set.init[i];
stage.balloon_pool.set[set].init[i].y, createBalloon(p.x, p.y, p.type, p.size, p.vel_x, balloon_speed_, p.creation_counter);
stage.balloon_pool.set[set].init[i].type,
stage.balloon_pool.set[set].init[i].size,
stage.balloon_pool.set[set].init[i].vel_x,
balloon_speed_,
stage.balloon_pool.set[set].init[i].creation_counter);
} }
balloon_deploy_counter_ = 300; balloon_deploy_counter_ = 300;
@@ -476,34 +471,17 @@ void Game::setBalloonSpeed(float speed)
// Actualiza la velocidad de los globos en funcion del poder acumulado de la fase // Actualiza la velocidad de los globos en funcion del poder acumulado de la fase
void Game::updateBalloonSpeed() void Game::updateBalloonSpeed()
{ {
const float percent = (float)current_power_ / (float)balloon_formations_->getStage(current_stage_).power_to_complete; const float percent = static_cast<float>(current_power_) / balloon_formations_->getStage(current_stage_).power_to_complete;
float old_balloon_speed = balloon_speed_; const float thresholds[] = {0.2f, 0.4f, 0.6f, 0.8f};
// Comprueba si se ha de modificar la velocidad de los globos for (size_t i = 0; i < std::size(thresholds); ++i)
if (balloon_speed_ == BALLOON_SPEED_1 && percent > 0.2f)
{ {
balloon_speed_ = BALLOON_SPEED_2; if (balloon_speed_ == BALLOON_SPEED[i] && percent > thresholds[i])
} {
balloon_speed_ = BALLOON_SPEED[i + 1];
else if (balloon_speed_ == BALLOON_SPEED_2 && percent > 0.4f) setBalloonSpeed(balloon_speed_);
{ break; // Salir del bucle una vez actualizada la velocidad y aplicada
balloon_speed_ = BALLOON_SPEED_3; }
}
else if (balloon_speed_ == BALLOON_SPEED_3 && percent > 0.6f)
{
balloon_speed_ = BALLOON_SPEED_4;
}
else if (balloon_speed_ == BALLOON_SPEED_4 && percent > 0.8f)
{
balloon_speed_ = BALLOON_SPEED_5;
}
// Si ha habido cambio, se aplica a todos los globos
if (old_balloon_speed != balloon_speed_)
{
setBalloonSpeed(balloon_speed_);
} }
} }
@@ -534,11 +512,11 @@ void Game::popBalloon(std::shared_ptr<Balloon> balloon)
const auto lower_size = static_cast<BalloonSize>(size - 1); const auto lower_size = static_cast<BalloonSize>(size - 1);
// En cualquier otro caso, crea dos globos de un tipo inferior // En cualquier otro caso, crea dos globos de un tipo inferior
auto balloon_left = createBalloon(0, balloon->getPosY(), balloon->getType(), lower_size, BALLOON_VELX_NEGATIVE, balloon_speed_, 0); auto balloon_left = createBalloon(0, balloon->getPosY(), balloon->getType(), lower_size, BALLOON_VELX_NEGATIVE, balloon_speed_, 0);
balloon_left->allignTo(balloon->getPosX() + (balloon->getWidth() / 2)); balloon_left->alignTo(balloon->getPosX() + (balloon->getWidth() / 2));
balloon_left->setVelY(balloon_left->getType() == BalloonType::BALLOON ? -2.50f : BALLOON_VELX_NEGATIVE * 2.0f); balloon_left->setVelY(balloon_left->getType() == BalloonType::BALLOON ? -2.50f : BALLOON_VELX_NEGATIVE * 2.0f);
auto balloon_right = createBalloon(0, balloon->getPosY(), balloon->getType(), lower_size, BALLOON_VELX_POSITIVE, balloon_speed_, 0); auto balloon_right = createBalloon(0, balloon->getPosY(), balloon->getType(), lower_size, BALLOON_VELX_POSITIVE, balloon_speed_, 0);
balloon_right->allignTo(balloon->getPosX() + (balloon->getWidth() / 2)); balloon_right->alignTo(balloon->getPosX() + (balloon->getWidth() / 2));
balloon_right->setVelY(balloon_right->getType() == BalloonType::BALLOON ? -2.50f : BALLOON_VELX_NEGATIVE * 2.0f); balloon_right->setVelY(balloon_right->getType() == BalloonType::BALLOON ? -2.50f : BALLOON_VELX_NEGATIVE * 2.0f);
// Elimina el globo // Elimina el globo
@@ -2167,7 +2145,7 @@ void Game::initDifficultyVars()
{ {
case GameDifficulty::EASY: case GameDifficulty::EASY:
{ {
default_balloon_speed_ = BALLOON_SPEED_1; default_balloon_speed_ = BALLOON_SPEED[0];
difficulty_score_multiplier_ = 0.5f; difficulty_score_multiplier_ = 0.5f;
scoreboard_->setColor(scoreboard_easy_color); scoreboard_->setColor(scoreboard_easy_color);
break; break;
@@ -2175,7 +2153,7 @@ void Game::initDifficultyVars()
case GameDifficulty::NORMAL: case GameDifficulty::NORMAL:
{ {
default_balloon_speed_ = BALLOON_SPEED_1; default_balloon_speed_ = BALLOON_SPEED[0];
difficulty_score_multiplier_ = 1.0f; difficulty_score_multiplier_ = 1.0f;
scoreboard_->setColor(scoreboard_normal_color); scoreboard_->setColor(scoreboard_normal_color);
break; break;
@@ -2183,7 +2161,7 @@ void Game::initDifficultyVars()
case GameDifficulty::HARD: case GameDifficulty::HARD:
{ {
default_balloon_speed_ = BALLOON_SPEED_5; default_balloon_speed_ = BALLOON_SPEED[4];
difficulty_score_multiplier_ = 1.5f; difficulty_score_multiplier_ = 1.5f;
scoreboard_->setColor(scoreboard_hard_color); scoreboard_->setColor(scoreboard_hard_color);
break; break;