cleanup time-based: elimina entitats frame-based (Bullet/Item/Player/Balloon), VELX en px/s, Game::popBalloon amb vel en px/s

This commit is contained in:
2026-05-19 18:28:14 +02:00
parent 2a69eaf041
commit 635662d65d
9 changed files with 95 additions and 694 deletions
+35 -321
View File
@@ -18,32 +18,19 @@ Balloon::Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 c
switch (kind) {
case BALLOON_1:
// Alto y ancho del objeto
width_ = WIDTH_1;
height_ = WIDTH_1;
size_ = SIZE_1;
power_ = 1;
// Inicializa los valores de velocidad y gravedad (frame-based)
this->vel_x_ = velx;
vel_y_ = 0;
max_vel_y_ = 3.0F;
gravity_ = 0.09F;
default_vel_y_ = 2.6F;
// Time-based equivalents (x60 per vel, x3600 per gravetat)
vel_x_s_ = velx * 60.0F;
vel_x_s_ = velx;
vel_y_s_ = 0.0F;
max_vel_y_s_ = 180.0F;
gravity_s_ = 324.0F;
default_vel_y_s_ = 156.0F;
// Puntos que da el globo al ser destruido
score_ = SCORE_1;
// Amenaza que genera el globo
menace_ = 1;
break;
case BALLOON_2:
@@ -52,13 +39,7 @@ Balloon::Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 c
size_ = SIZE_2;
power_ = 3;
this->vel_x_ = velx;
vel_y_ = 0;
max_vel_y_ = 3.0F;
gravity_ = 0.10F;
default_vel_y_ = 3.5F;
vel_x_s_ = velx * 60.0F;
vel_x_s_ = velx;
vel_y_s_ = 0.0F;
max_vel_y_s_ = 180.0F;
gravity_s_ = 360.0F;
@@ -74,13 +55,7 @@ Balloon::Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 c
size_ = SIZE_3;
power_ = 7;
this->vel_x_ = velx;
vel_y_ = 0;
max_vel_y_ = 3.0F;
gravity_ = 0.10F;
default_vel_y_ = 4.50F;
vel_x_s_ = velx * 60.0F;
vel_x_s_ = velx;
vel_y_s_ = 0.0F;
max_vel_y_s_ = 180.0F;
gravity_s_ = 360.0F;
@@ -96,13 +71,7 @@ Balloon::Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 c
size_ = SIZE_4;
power_ = 15;
this->vel_x_ = velx;
vel_y_ = 0;
max_vel_y_ = 3.0F;
gravity_ = 0.10F;
default_vel_y_ = 4.95F;
vel_x_s_ = velx * 60.0F;
vel_x_s_ = velx;
vel_y_s_ = 0.0F;
max_vel_y_s_ = 180.0F;
gravity_s_ = 360.0F;
@@ -118,17 +87,11 @@ Balloon::Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 c
size_ = SIZE_1;
power_ = 1;
this->vel_x_ = velx;
vel_y_ = std::fabs(velx) * 2;
max_vel_y_ = std::fabs(velx) * 2;
gravity_ = 0.00F;
default_vel_y_ = std::fabs(velx) * 2;
vel_x_s_ = velx * 60.0F;
vel_y_s_ = std::fabs(velx) * 2.0F * 60.0F;
max_vel_y_s_ = std::fabs(velx) * 2.0F * 60.0F;
vel_x_s_ = velx;
vel_y_s_ = std::fabs(velx) * 2.0F;
max_vel_y_s_ = std::fabs(velx) * 2.0F;
gravity_s_ = 0.0F;
default_vel_y_s_ = std::fabs(velx) * 2.0F * 60.0F;
default_vel_y_s_ = std::fabs(velx) * 2.0F;
score_ = SCORE_1;
menace_ = 1;
@@ -140,17 +103,11 @@ Balloon::Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 c
size_ = SIZE_2;
power_ = 3;
this->vel_x_ = velx;
vel_y_ = std::fabs(velx) * 2;
max_vel_y_ = std::fabs(velx) * 2;
gravity_ = 0.00F;
default_vel_y_ = std::fabs(velx) * 2;
vel_x_s_ = velx * 60.0F;
vel_y_s_ = std::fabs(velx) * 2.0F * 60.0F;
max_vel_y_s_ = std::fabs(velx) * 2.0F * 60.0F;
vel_x_s_ = velx;
vel_y_s_ = std::fabs(velx) * 2.0F;
max_vel_y_s_ = std::fabs(velx) * 2.0F;
gravity_s_ = 0.0F;
default_vel_y_s_ = std::fabs(velx) * 2.0F * 60.0F;
default_vel_y_s_ = std::fabs(velx) * 2.0F;
score_ = SCORE_2;
menace_ = 2;
@@ -162,17 +119,11 @@ Balloon::Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 c
size_ = SIZE_3;
power_ = 7;
this->vel_x_ = velx;
vel_y_ = std::fabs(velx) * 2;
max_vel_y_ = std::fabs(velx) * 2;
gravity_ = 0.00F;
default_vel_y_ = std::fabs(velx) * 2;
vel_x_s_ = velx * 60.0F;
vel_y_s_ = std::fabs(velx) * 2.0F * 60.0F;
max_vel_y_s_ = std::fabs(velx) * 2.0F * 60.0F;
vel_x_s_ = velx;
vel_y_s_ = std::fabs(velx) * 2.0F;
max_vel_y_s_ = std::fabs(velx) * 2.0F;
gravity_s_ = 0.0F;
default_vel_y_s_ = std::fabs(velx) * 2.0F * 60.0F;
default_vel_y_s_ = std::fabs(velx) * 2.0F;
score_ = SCORE_3;
menace_ = 4;
@@ -184,17 +135,11 @@ Balloon::Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 c
size_ = SIZE_4;
power_ = 15;
this->vel_x_ = velx;
vel_y_ = std::fabs(velx) * 2;
max_vel_y_ = std::fabs(velx) * 2;
gravity_ = 0.00F;
default_vel_y_ = std::fabs(velx) * 2;
vel_x_s_ = velx * 60.0F;
vel_y_s_ = std::fabs(velx) * 2.0F * 60.0F;
max_vel_y_s_ = std::fabs(velx) * 2.0F * 60.0F;
vel_x_s_ = velx;
vel_y_s_ = std::fabs(velx) * 2.0F;
max_vel_y_s_ = std::fabs(velx) * 2.0F;
gravity_s_ = 0.0F;
default_vel_y_s_ = std::fabs(velx) * 2.0F * 60.0F;
default_vel_y_s_ = std::fabs(velx) * 2.0F;
score_ = SCORE_4;
menace_ = 8;
@@ -206,13 +151,7 @@ Balloon::Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 c
size_ = 4;
power_ = 0;
this->vel_x_ = velx;
vel_y_ = 0;
max_vel_y_ = 3.0F;
gravity_ = 0.10F;
default_vel_y_ = 4.95F;
vel_x_s_ = velx * 60.0F;
vel_x_s_ = velx;
vel_y_s_ = 0.0F;
max_vel_y_s_ = 180.0F;
gravity_s_ = 360.0F;
@@ -229,7 +168,7 @@ Balloon::Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 c
// sempre que canvia. setRotateSpeed(1) evita la UB del `counter_
// % 0` dins MovingSprite::rotate().
sprite_->setRotateSpeed(1);
sprite_->setRotateAmount(vel_x_ > 0.0F ? 2.0 : -2.0);
sprite_->setRotateAmount(vel_x_s_ > 0.0F ? 2.0 : -2.0);
break;
@@ -284,8 +223,6 @@ Balloon::Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 c
being_created_ = creation_counter_ != 0;
invulnerable_ = being_created_;
counter_ = 0;
travel_y_ = 1.0F;
this->speed_ = speed;
// Tipo
@@ -351,96 +288,8 @@ void Balloon::render() {
}
}
// Actualiza la posición y estados del globo
void Balloon::move() {
// Comprueba si se puede mover
if (!isStopped()) {
// Lo mueve a izquierda o derecha
pos_x_ += (vel_x_ * speed_);
// Si queda fuera de pantalla, corregimos su posición y cambiamos su sentido
if ((pos_x_ < PLAY_AREA_LEFT) || (pos_x_ + width_ > PLAY_AREA_RIGHT)) {
// Corrige posición
pos_x_ -= (vel_x_ * speed_);
// Invierte sentido
vel_x_ = -vel_x_;
// Invierte la rotación
sprite_->switchRotate();
// Activa el efecto de rebote
if (kind_ != POWER_BALL) {
bounceStart();
}
}
// Mueve el globo hacia arriba o hacia abajo
pos_y_ += (vel_y_ * speed_);
// Si se sale por arriba
if (pos_y_ < PLAY_AREA_TOP) {
// Corrige
pos_y_ = PLAY_AREA_TOP;
// Invierte sentido
vel_y_ = -vel_y_;
// Activa el efecto de rebote
if (kind_ != POWER_BALL) {
bounceStart();
}
}
// Si el globo se sale por la parte inferior
if (pos_y_ + height_ > PLAY_AREA_BOTTOM) {
// Corrige
pos_y_ = PLAY_AREA_BOTTOM - height_;
// Invierte colocando una velocidad por defecto
vel_y_ = -default_vel_y_;
// Activa el efecto de rebote
if (kind_ != POWER_BALL) {
bounceStart();
}
}
/*
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
vel_y_ += gravity_;
// Al parecer esta asignación se quedó sin hacer y ahora el juego no funciona
// correctamente si se aplica, así que se deja sin efecto
// velY = std::min(velY, maxVelY);
}
// Actualiza la posición del sprite
sprite_->setPosX(getPosX());
sprite_->setPosY(getPosY());
}
}
// Actualiza la posición y estados del globo (time-based).
// Reemplaça l'acumulador `travel_y_` per integració contínua: gravetat i
// posició s'apliquen escalades per `speed_` (tempo del joc) cada tick,
// equivalent en mitjana a l'original però sense l'efecte chunky.
// Actualiza la posición y estados del globo. Integració contínua: gravetat i
// posició s'apliquen escalades per `speed_` (tempo del joc) cada tick.
void Balloon::move(float dt_s) {
if (!isStopped()) {
// Eix X
@@ -449,7 +298,6 @@ void Balloon::move(float dt_s) {
if ((pos_x_ < PLAY_AREA_LEFT) || (pos_x_ + width_ > PLAY_AREA_RIGHT)) {
pos_x_ -= vel_x_s_ * speed_ * dt_s;
vel_x_s_ = -vel_x_s_;
vel_x_ = -vel_x_; // mantenir frame-based sincronitzat (UB-free per a sprite->switchRotate)
sprite_->switchRotate();
if (kind_ != POWER_BALL) { bounceStart(); }
}
@@ -460,19 +308,16 @@ void Balloon::move(float dt_s) {
if (pos_y_ < PLAY_AREA_TOP) {
pos_y_ = PLAY_AREA_TOP;
vel_y_s_ = -vel_y_s_;
vel_y_ = -vel_y_;
if (kind_ != POWER_BALL) { bounceStart(); }
}
if (pos_y_ + height_ > PLAY_AREA_BOTTOM) {
pos_y_ = PLAY_AREA_BOTTOM - height_;
vel_y_s_ = -default_vel_y_s_;
vel_y_ = -default_vel_y_;
if (kind_ != POWER_BALL) { bounceStart(); }
}
// Gravetat contínua (el tempo `speed_` escala també la gravetat per
// mantenir el mateix patró de rebot que la versió frame-based).
// Gravetat contínua (el tempo `speed_` escala també la gravetat).
vel_y_s_ += gravity_s_ * speed_ * dt_s;
sprite_->setPosX(getPosX());
@@ -487,22 +332,18 @@ void Balloon::disable() {
collider_.r = 0;
collider_.x = 0;
collider_.y = 0;
counter_ = 0;
creation_counter_ = 0;
creation_counter_ini_ = 0;
creation_counter_s_ = 0.0F;
creation_counter_ini_s_ = 0.0F;
creation_phase_s_ = 0.0F;
bounce_phase_s_ = 0.0F;
default_vel_y_ = 0.0F;
default_vel_y_s_ = 0.0F;
enabled_ = false;
gravity_ = 0.0F;
gravity_s_ = 0.0F;
height_ = 0;
invulnerable_ = false;
kind_ = 0;
max_vel_y_ = 0.0F;
max_vel_y_s_ = 0.0F;
menace_ = 0;
popping_ = false;
@@ -515,9 +356,6 @@ void Balloon::disable() {
stopped_ = false;
stopped_counter_ = 0;
stopped_counter_s_ = 0.0F;
travel_y_ = 0;
vel_x_ = 0.0F;
vel_y_ = 0.0F;
vel_x_s_ = 0.0F;
vel_y_s_ = 0.0F;
visible_ = false;
@@ -536,19 +374,6 @@ void Balloon::pop() {
}
// Actualiza al globo a su posicion, animación y controla los contadores
void Balloon::update() {
if (enabled_) {
sprite_->MovingSprite::update();
move();
updateAnimation();
updateColliders();
updateState();
updateBounce();
counter_++;
}
}
// Actualiza al globo (time-based)
void Balloon::update(float dt_s) {
if (enabled_) {
// MovingSprite::update(dt_s) avança la rotació (entre altres). La posició
@@ -563,21 +388,6 @@ void Balloon::update(float dt_s) {
}
// Actualiza los estados del globo
void Balloon::updateState() {
if (isPopping()) {
updateStatePopping();
}
if (isBeingCreated()) {
updateStateBeingCreated();
}
// Solo comprueba el estado detenido cuando no se está creando
else if (isStopped()) {
updateStateStopped();
}
}
// Actualiza los estados del globo (time-based)
void Balloon::updateState(float dt_s) {
if (isPopping()) {
updateStatePopping();
@@ -599,46 +409,10 @@ void Balloon::updateStatePopping() {
}
}
// Rama de updateState: globo creándose
void Balloon::updateStateBeingCreated() {
setStop(true);
setInvulnerable(true);
// Todavia tiene tiempo en el contador
if (creation_counter_ > 0) {
// Desplaza lentamente el globo hacia abajo y hacia un lado
if (creation_counter_ % 10 == 0) {
pos_y_++;
pos_x_ += vel_x_;
// Comprueba no se salga por los laterales
if ((pos_x_ < PLAY_AREA_LEFT) || (pos_x_ > (PLAY_AREA_RIGHT - width_))) {
// Corrige y cambia el sentido de la velocidad
pos_x_ -= vel_x_;
vel_x_ = -vel_x_;
}
// Actualiza la posición del sprite
sprite_->setPosX(getPosX());
sprite_->setPosY(getPosY());
// Actualiza la posición del circulo de colisión
updateColliders();
}
creation_counter_--;
}
// El contador ha llegado a cero
else {
setBeingCreated(false);
setStop(false); // reactiva la rotació de la PowerBall si escau
setVisible(true);
setInvulnerable(false);
}
}
// Rama de updateState: globo creándose (time-based). Manté el chunk pattern
// original: cada CREATION_STEP_S s'aplica un step de drift.
// Rama de updateState: globo creándose. Manté el chunk pattern original:
// cada CREATION_STEP_S s'aplica un step de drift (equivalent a "cada 10
// frames" del codi original). El drift en X usa vel_x_s_/60 per a obtenir
// el mateix delta px-per-step.
void Balloon::updateStateBeingCreated(float dt_s) {
setStop(true);
setInvulnerable(true);
@@ -648,11 +422,11 @@ void Balloon::updateStateBeingCreated(float dt_s) {
while (creation_phase_s_ >= CREATION_STEP_S) {
creation_phase_s_ -= CREATION_STEP_S;
pos_y_ += 1.0F;
pos_x_ += vel_x_; // drift idèntic a l'original (vel_x_ en px/frame)
const float DRIFT_X = vel_x_s_ / 60.0F;
pos_x_ += DRIFT_X;
if ((pos_x_ < PLAY_AREA_LEFT) || (pos_x_ > (PLAY_AREA_RIGHT - width_))) {
pos_x_ -= vel_x_;
vel_x_ = -vel_x_;
pos_x_ -= DRIFT_X;
vel_x_s_ = -vel_x_s_;
}
@@ -672,18 +446,6 @@ void Balloon::updateStateBeingCreated(float dt_s) {
}
// Rama de updateState: globo detenido (no creándose)
void Balloon::updateStateStopped() {
// Reduce el contador
if (stopped_counter_ > 0) {
stopped_counter_--;
}
// Quitarles el estado "detenido" si no estan explosionando
else if (!isPopping()) {
setStop(false); // reactiva la rotació de la PowerBall si escau
}
}
// Rama de updateState: globo detenido (time-based)
void Balloon::updateStateStopped(float dt_s) {
if (stopped_counter_s_ > 0.0F) {
stopped_counter_s_ = std::max(0.0F, stopped_counter_s_ - dt_s);
@@ -694,31 +456,6 @@ void Balloon::updateStateStopped(float dt_s) {
}
// Establece la animación correspondiente al estado
void Balloon::updateAnimation() {
std::string creating_animation = "blue";
std::string normal_animation = "orange";
if (kind_ == POWER_BALL) {
creating_animation = "powerball";
normal_animation = "powerball";
} else if (getClass() == HEXAGON_CLASS) {
creating_animation = "red";
normal_animation = "green";
}
// Establece el frame de animación
if (isPopping()) {
sprite_->setCurrentAnimation("pop");
} else if (isBeingCreated()) {
sprite_->setCurrentAnimation(creating_animation);
} else {
sprite_->setCurrentAnimation(normal_animation);
}
sprite_->animate();
}
// Establece la animación correspondiente (time-based)
void Balloon::updateAnimation(float dt_s) {
std::string creating_animation = "blue";
std::string normal_animation = "orange";
@@ -757,11 +494,6 @@ auto Balloon::getPosY() const -> float {
return pos_y_;
}
// Obtiene del valor de la variable
auto Balloon::getVelY() const -> float {
return vel_y_;
}
// Obtiene del valor de la variable
auto Balloon::getWidth() const -> int {
return width_;
@@ -772,10 +504,9 @@ auto Balloon::getHeight() const -> int {
return height_;
}
// Establece el valor de la variable
// Establece el valor de la variable (px/s)
void Balloon::setVelY(float vel_y) {
this->vel_y_ = vel_y;
this->vel_y_s_ = vel_y * 60.0F;
this->vel_y_s_ = vel_y;
}
// Establece el valor de la variable
@@ -933,23 +664,6 @@ void Balloon::bounceStop() {
bouncing_.desp_y = 0.0F;
}
void Balloon::updateBounce() {
if (bouncing_.enabled) {
bouncing_.zoom_width = bouncing_.w[bouncing_.counter / bouncing_.speed];
bouncing_.zoom_height = bouncing_.h[bouncing_.counter / bouncing_.speed];
sprite_->setZoomW(bouncing_.zoom_width);
sprite_->setZoomH(bouncing_.zoom_height);
bouncing_.desp_x = (sprite_->getSpriteClip().w - (sprite_->getSpriteClip().w * bouncing_.zoom_width));
bouncing_.desp_y = (sprite_->getSpriteClip().h - (sprite_->getSpriteClip().h * bouncing_.zoom_height));
bouncing_.counter++;
if ((bouncing_.counter / bouncing_.speed) > (MAX_BOUNCE - 1)) {
bounceStop();
}
}
}
// Aplica l'efecte de rebote (time-based). Manté la mateixa cadència: cada
// `bouncing_.speed` "frames" (a 60Hz) avança un slot del vector w/h.
void Balloon::updateBounce(float dt_s) {
if (!bouncing_.enabled) { return; }
@@ -973,4 +687,4 @@ void Balloon::updateBounce(float dt_s) {
sprite_->setZoomH(bouncing_.zoom_height);
bouncing_.desp_x = (sprite_->getSpriteClip().w - (sprite_->getSpriteClip().w * bouncing_.zoom_width));
bouncing_.desp_y = (sprite_->getSpriteClip().h - (sprite_->getSpriteClip().h * bouncing_.zoom_height));
}
}