Implementar sistema de variación por rebote individual
- Corregir coeficiente base: ahora TODAS las pelotas tienen el mismo (0.75) - Añadir constantes configurables en defines.h: * BASE_BOUNCE_COEFFICIENT = 0.75f (igual para todas) * BOUNCE_VARIATION_PERCENT = 0.05f (±5% por rebote) * LATERAL_LOSS_PERCENT = 0.02f (±2% pérdida lateral) - Implementar funciones generateBounceVariation() y generateLateralLoss() - Aplicar variación aleatoria en cada rebote individual: * Superficie de gravedad: rebote con ±5% variación * Otras superficies: pérdida lateral 0-2% - Añadir pérdida lateral perpendicular en todos los rebotes - Actualizar debug display para mostrar coeficiente LOSS Efecto: Pelotas idénticas divergen gradualmente por variaciones microscópicas acumulativas, eliminando sincronización de forma natural y realista. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,20 @@
|
||||
#include "defines.h" // for BALL_SIZE, Color, SCREEN_HEIGHT, GRAVITY_FORCE
|
||||
class Texture;
|
||||
|
||||
// Función auxiliar para generar variación aleatoria en rebotes
|
||||
float generateBounceVariation() {
|
||||
// Genera un valor entre -BOUNCE_VARIATION_PERCENT y +BOUNCE_VARIATION_PERCENT
|
||||
float variation = ((rand() % 1000) / 1000.0f - 0.5f) * 2.0f * BOUNCE_VARIATION_PERCENT;
|
||||
return 1.0f + variation; // Retorna multiplicador (ej: 0.95 - 1.05 para ±5%)
|
||||
}
|
||||
|
||||
// Función auxiliar para generar pérdida lateral aleatoria
|
||||
float generateLateralLoss() {
|
||||
// Genera un valor entre 0 y LATERAL_LOSS_PERCENT
|
||||
float loss = (rand() % 1000) / 1000.0f * LATERAL_LOSS_PERCENT;
|
||||
return 1.0f - loss; // Retorna multiplicador (ej: 0.98 - 1.0 para 0-2% pérdida)
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Ball::Ball(float x, float vx, float vy, Color color, std::shared_ptr<Texture> texture, GravityDirection gravity_dir)
|
||||
: sprite_(std::make_unique<Sprite>(texture)),
|
||||
@@ -23,7 +37,8 @@ Ball::Ball(float x, float vx, float vy, Color color, std::shared_ptr<Texture> te
|
||||
gravity_direction_ = gravity_dir;
|
||||
on_surface_ = false;
|
||||
stopped_ = false;
|
||||
loss_ = ((rand() % 30) * 0.01f) + 0.6f;
|
||||
// Coeficiente base IGUAL para todas las pelotas (solo variación por rebote individual)
|
||||
loss_ = BASE_BOUNCE_COEFFICIENT; // Coeficiente fijo para todas las pelotas
|
||||
}
|
||||
|
||||
// Actualiza la lógica de la clase
|
||||
@@ -80,64 +95,72 @@ void Ball::update(float deltaTime) {
|
||||
if (pos_.x < 0) {
|
||||
pos_.x = 0;
|
||||
if (gravity_direction_ == GravityDirection::LEFT) {
|
||||
// Colisión con superficie de gravedad
|
||||
vx_ = -vx_ * loss_;
|
||||
// Colisión con superficie de gravedad - aplicar variación aleatoria
|
||||
vx_ = -vx_ * loss_ * generateBounceVariation();
|
||||
if (std::fabs(vx_) < 6.0f) {
|
||||
vx_ = 0.0f;
|
||||
on_surface_ = true;
|
||||
}
|
||||
} else {
|
||||
// Rebote normal
|
||||
vx_ = -vx_;
|
||||
// Rebote normal - con pérdida lateral aleatoria
|
||||
vx_ = -vx_ * generateLateralLoss();
|
||||
}
|
||||
// Pérdida lateral en velocidad vertical también
|
||||
vy_ *= generateLateralLoss();
|
||||
}
|
||||
|
||||
// Comprueba las colisiones con el lateral derecho
|
||||
if (pos_.x + pos_.w > SCREEN_WIDTH) {
|
||||
pos_.x = SCREEN_WIDTH - pos_.w;
|
||||
if (gravity_direction_ == GravityDirection::RIGHT) {
|
||||
// Colisión con superficie de gravedad
|
||||
vx_ = -vx_ * loss_;
|
||||
// Colisión con superficie de gravedad - aplicar variación aleatoria
|
||||
vx_ = -vx_ * loss_ * generateBounceVariation();
|
||||
if (std::fabs(vx_) < 6.0f) {
|
||||
vx_ = 0.0f;
|
||||
on_surface_ = true;
|
||||
}
|
||||
} else {
|
||||
// Rebote normal
|
||||
vx_ = -vx_;
|
||||
// Rebote normal - con pérdida lateral aleatoria
|
||||
vx_ = -vx_ * generateLateralLoss();
|
||||
}
|
||||
// Pérdida lateral en velocidad vertical también
|
||||
vy_ *= generateLateralLoss();
|
||||
}
|
||||
|
||||
// Comprueba las colisiones con la parte superior
|
||||
if (pos_.y < 0) {
|
||||
pos_.y = 0;
|
||||
if (gravity_direction_ == GravityDirection::UP) {
|
||||
// Colisión con superficie de gravedad
|
||||
vy_ = -vy_ * loss_;
|
||||
// Colisión con superficie de gravedad - aplicar variación aleatoria
|
||||
vy_ = -vy_ * loss_ * generateBounceVariation();
|
||||
if (std::fabs(vy_) < 6.0f) {
|
||||
vy_ = 0.0f;
|
||||
on_surface_ = true;
|
||||
}
|
||||
} else {
|
||||
// Rebote normal
|
||||
vy_ = -vy_;
|
||||
// Rebote normal - con pérdida lateral aleatoria
|
||||
vy_ = -vy_ * generateLateralLoss();
|
||||
}
|
||||
// Pérdida lateral en velocidad horizontal también
|
||||
vx_ *= generateLateralLoss();
|
||||
}
|
||||
|
||||
// Comprueba las colisiones con la parte inferior
|
||||
if (pos_.y + pos_.h > SCREEN_HEIGHT) {
|
||||
pos_.y = SCREEN_HEIGHT - pos_.h;
|
||||
if (gravity_direction_ == GravityDirection::DOWN) {
|
||||
// Colisión con superficie de gravedad
|
||||
vy_ = -vy_ * loss_;
|
||||
// Colisión con superficie de gravedad - aplicar variación aleatoria
|
||||
vy_ = -vy_ * loss_ * generateBounceVariation();
|
||||
if (std::fabs(vy_) < 6.0f) {
|
||||
vy_ = 0.0f;
|
||||
on_surface_ = true;
|
||||
}
|
||||
} else {
|
||||
// Rebote normal
|
||||
vy_ = -vy_;
|
||||
// Rebote normal - con pérdida lateral aleatoria
|
||||
vy_ = -vy_ * generateLateralLoss();
|
||||
}
|
||||
// Pérdida lateral en velocidad horizontal también
|
||||
vx_ *= generateLateralLoss();
|
||||
}
|
||||
|
||||
// Aplica rozamiento al estar en superficie
|
||||
|
||||
@@ -46,6 +46,7 @@ class Ball {
|
||||
float getVelocityY() const { return vy_; }
|
||||
float getVelocityX() const { return vx_; }
|
||||
float getGravityForce() const { return gravity_force_; }
|
||||
float getLossCoefficient() const { return loss_; }
|
||||
GravityDirection getGravityDirection() const { return gravity_direction_; }
|
||||
bool isOnSurface() const { return on_surface_; }
|
||||
|
||||
|
||||
@@ -11,6 +11,11 @@ constexpr float GRAVITY_FORCE = 0.2f;
|
||||
// DEMO_SPEED eliminado - ya no se usa con delta time
|
||||
constexpr Uint64 TEXT_DURATION = 2000;
|
||||
|
||||
// Configuración de variación aleatoria en rebotes
|
||||
constexpr float BASE_BOUNCE_COEFFICIENT = 0.75f; // Coeficiente base IGUAL para todas las pelotas
|
||||
constexpr float BOUNCE_VARIATION_PERCENT = 0.05f; // ±5% variación en cada rebote
|
||||
constexpr float LATERAL_LOSS_PERCENT = 0.02f; // ±2% pérdida lateral en rebotes
|
||||
|
||||
struct Color {
|
||||
int r, g, b;
|
||||
};
|
||||
|
||||
@@ -555,15 +555,20 @@ void render() {
|
||||
std::string surface_text = balls[0]->isOnSurface() ? "SURFACE YES" : "SURFACE NO";
|
||||
dbg_print(8, 40, surface_text.c_str(), 255, 0, 255); // Magenta para debug
|
||||
|
||||
// Línea 4: Dirección de gravedad
|
||||
// Línea 4: Coeficiente de rebote (loss)
|
||||
float loss_val = balls[0]->getLossCoefficient();
|
||||
std::string loss_text = "LOSS " + std::to_string(loss_val).substr(0, 4); // Solo 2 decimales
|
||||
dbg_print(8, 48, loss_text.c_str(), 255, 0, 255); // Magenta para debug
|
||||
|
||||
// Línea 5: Dirección de gravedad
|
||||
std::string gravity_dir_text = "GRAVITY " + gravityDirectionToString(current_gravity);
|
||||
dbg_print(8, 48, gravity_dir_text.c_str(), 255, 255, 0); // Amarillo para dirección
|
||||
dbg_print(8, 56, gravity_dir_text.c_str(), 255, 255, 0); // Amarillo para dirección
|
||||
}
|
||||
|
||||
// Debug: Mostrar tema actual
|
||||
std::string theme_names[] = {"SUNSET", "OCEAN", "NEON", "FOREST"};
|
||||
std::string theme_text = "THEME " + theme_names[static_cast<int>(current_theme)];
|
||||
dbg_print(8, 56, theme_text.c_str(), 255, 255, 128); // Amarillo claro para tema
|
||||
dbg_print(8, 64, theme_text.c_str(), 255, 255, 128); // Amarillo claro para tema
|
||||
}
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
|
||||
Reference in New Issue
Block a user