Implementar empuje lateral sutil al cambiar gravedad

🎯 Problema solucionado:
- Pelotas se movían en líneas perfectas al cambiar gravedad
- Todas llegaban exactamente una encima de otra

 Solución implementada:
- Empuje lateral aleatorio muy sutil (2.4-4.8 px/s)
- Se aplica automáticamente al cambiar dirección de gravedad
- Perpendicular a la gravedad: UP/DOWN → empuje X, LEFT/RIGHT → empuje Y

🔧 Implementación técnica:
- Nueva función Ball::applyRandomLateralPush()
- Integrada en Engine::changeGravityDirection()
- Velocidades ajustadas para ser apenas perceptibles

📊 Valores finales:
- GRAVITY_CHANGE_LATERAL_MIN = 0.04f (2.4 px/s)
- GRAVITY_CHANGE_LATERAL_MAX = 0.08f (4.8 px/s)
- Rango: ~3-5 píxeles en 1 segundo (muy sutil)

🎮 Resultado:
- Rompe la simetría perfecta sin crear caos
- Movimiento más natural y orgánico
- Mantiene la física realista

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-18 18:06:19 +02:00
parent a798811d23
commit 036268f135
4 changed files with 32 additions and 0 deletions

View File

@@ -224,3 +224,27 @@ void Ball::setGravityDirection(GravityDirection direction) {
on_surface_ = false; // Ya no está en superficie al cambiar dirección on_surface_ = false; // Ya no está en superficie al cambiar dirección
stopped_ = false; // Reactivar movimiento stopped_ = false; // Reactivar movimiento
} }
// Aplica un pequeño empuje lateral aleatorio
void Ball::applyRandomLateralPush() {
// Generar velocidad lateral aleatoria (nunca 0)
float lateral_speed = GRAVITY_CHANGE_LATERAL_MIN + (rand() % 1000) / 1000.0f * (GRAVITY_CHANGE_LATERAL_MAX - GRAVITY_CHANGE_LATERAL_MIN);
// Signo aleatorio (+ o -)
int sign = ((rand() % 2) * 2) - 1;
lateral_speed *= sign;
// Aplicar según la dirección de gravedad actual
switch (gravity_direction_) {
case GravityDirection::UP:
case GravityDirection::DOWN:
// Gravedad vertical -> empuje lateral en X
vx_ += lateral_speed * 60.0f; // Convertir a píxeles/segundo
break;
case GravityDirection::LEFT:
case GravityDirection::RIGHT:
// Gravedad horizontal -> empuje lateral en Y
vy_ += lateral_speed * 60.0f; // Convertir a píxeles/segundo
break;
}
}

View File

@@ -43,6 +43,9 @@ class Ball {
// Cambia la direcci\u00f3n de gravedad // Cambia la direcci\u00f3n de gravedad
void setGravityDirection(GravityDirection direction); void setGravityDirection(GravityDirection direction);
// Aplica un peque\u00f1o empuje lateral aleatorio
void applyRandomLateralPush();
// Getters para debug // Getters para debug
float getVelocityY() const { return vy_; } float getVelocityY() const { return vy_; }
float getVelocityX() const { return vx_; } float getVelocityX() const { return vx_; }

View File

@@ -20,6 +20,10 @@ constexpr float LATERAL_LOSS_PERCENT = 0.02f; // ±2% pérdida lateral en r
constexpr float GRAVITY_MASS_MIN = 0.7f; // Factor mínimo de masa (pelota ligera - 70% gravedad) constexpr float GRAVITY_MASS_MIN = 0.7f; // Factor mínimo de masa (pelota ligera - 70% gravedad)
constexpr float GRAVITY_MASS_MAX = 1.3f; // Factor máximo de masa (pelota pesada - 130% gravedad) constexpr float GRAVITY_MASS_MAX = 1.3f; // Factor máximo de masa (pelota pesada - 130% gravedad)
// Configuración de velocidad lateral al cambiar gravedad (muy sutil)
constexpr float GRAVITY_CHANGE_LATERAL_MIN = 0.04f; // Velocidad lateral mínima (2.4 px/s)
constexpr float GRAVITY_CHANGE_LATERAL_MAX = 0.08f; // Velocidad lateral máxima (4.8 px/s)
struct Color { struct Color {
int r, g, b; int r, g, b;
}; };

View File

@@ -388,6 +388,7 @@ void Engine::changeGravityDirection(GravityDirection direction) {
current_gravity_ = direction; current_gravity_ = direction;
for (auto &ball : balls_) { for (auto &ball : balls_) {
ball->setGravityDirection(direction); ball->setGravityDirection(direction);
ball->applyRandomLateralPush(); // Aplicar empuje lateral aleatorio
} }
} }