Fix: Sistema de convergencia y flip timing en LOGO mode

Refactoring semántico:
- Renombrar rotoball_* → shape_* (variables y métodos)
- Mejora legibilidad: aplica a todas las figuras 3D, no solo esfera

Fixes críticos:
- Fix convergencia: setShapeTarget2D() actualiza targets cada frame
- Fix getDistanceToTarget(): siempre calcula distancia (sin guarda)
- Fix lógica flip: destruir DURANTE flip N (no después de N flips)
- Añadir display CONV en debug HUD (monitoreo convergencia)

Mejoras timing:
- Reducir PNG_IDLE_TIME_LOGO: 3-5s → 2-4s (flips más dinámicos)
- Bajar CONVERGENCE_THRESHOLD: 0.8 → 0.4 (40% permite flips)

Sistema flip-waiting (LOGO mode):
- CAMINO A: Convergencia + tiempo (inmediato)
- CAMINO B: Esperar 1-3 flips y destruir durante flip (20-80% progreso)
- Tracking de flips con getFlipCount() y getFlipProgress()

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-09 11:01:41 +02:00
parent 6cb3c2eef9
commit b93028396a
8 changed files with 238 additions and 52 deletions

View File

@@ -42,7 +42,7 @@ Ball::Ball(float x, float vx, float vy, Color color, std::shared_ptr<Texture> te
// Coeficiente base IGUAL para todas las pelotas (solo variación por rebote individual)
loss_ = BASE_BOUNCE_COEFFICIENT; // Coeficiente fijo para todas las pelotas
// Inicializar valores RotoBall
// Inicializar valores Shape (figuras 3D)
pos_3d_x_ = 0.0f;
pos_3d_y_ = 0.0f;
pos_3d_z_ = 0.0f;
@@ -50,7 +50,7 @@ Ball::Ball(float x, float vx, float vy, Color color, std::shared_ptr<Texture> te
target_y_ = pos_.y;
depth_brightness_ = 1.0f;
depth_scale_ = 1.0f;
rotoball_attraction_active_ = false;
shape_attraction_active_ = false;
}
// Actualiza la lógica de la clase
@@ -267,19 +267,19 @@ void Ball::applyRandomLateralPush() {
}
}
// Funciones para modo RotoBall
void Ball::setRotoBallPosition3D(float x, float y, float z) {
// Funciones para modo Shape (figuras 3D)
void Ball::setShapePosition3D(float x, float y, float z) {
pos_3d_x_ = x;
pos_3d_y_ = y;
pos_3d_z_ = z;
}
void Ball::setRotoBallTarget2D(float x, float y) {
void Ball::setShapeTarget2D(float x, float y) {
target_x_ = x;
target_y_ = y;
}
void Ball::setRotoBallScreenPosition(float x, float y) {
void Ball::setShapeScreenPosition(float x, float y) {
pos_.x = x;
pos_.y = y;
sprite_->setPos({x, y});
@@ -293,9 +293,9 @@ void Ball::setDepthScale(float scale) {
depth_scale_ = scale;
}
// Activar/desactivar atracción física hacia esfera RotoBall
void Ball::enableRotoBallAttraction(bool enable) {
rotoball_attraction_active_ = enable;
// Activar/desactivar atracción física hacia figuras 3D
void Ball::enableShapeAttraction(bool enable) {
shape_attraction_active_ = enable;
// Al activar atracción, resetear flags de superficie para permitir física completa
if (enable) {
@@ -305,18 +305,17 @@ void Ball::enableRotoBallAttraction(bool enable) {
// Obtener distancia actual al punto objetivo (para calcular convergencia)
float Ball::getDistanceToTarget() const {
if (!rotoball_attraction_active_) return 0.0f;
// Siempre calcular distancia (útil para convergencia en LOGO mode)
float dx = target_x_ - pos_.x;
float dy = target_y_ - pos_.y;
return sqrtf(dx * dx + dy * dy);
}
// Aplicar fuerza de resorte hacia punto objetivo en figuras 3D
void Ball::applyRotoBallForce(float target_x, float target_y, float sphere_radius, float deltaTime,
float spring_k_base, float damping_base_base, float damping_near_base,
float near_threshold_base, float max_force_base) {
if (!rotoball_attraction_active_) return;
void Ball::applyShapeForce(float target_x, float target_y, float sphere_radius, float deltaTime,
float spring_k_base, float damping_base_base, float damping_near_base,
float near_threshold_base, float max_force_base) {
if (!shape_attraction_active_) return;
// Calcular factor de escala basado en el radio (radio base = 80px)
// Si radius=80 → scale=1.0, si radius=160 → scale=2.0, si radius=360 → scale=4.5