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

@@ -268,7 +268,15 @@ std::vector<PNGShape::Point2D> PNGShape::extractCornerVertices(const std::vector
void PNGShape::update(float delta_time, float screen_width, float screen_height) {
if (!is_flipping_) {
// Estado IDLE: texto de frente con pivoteo sutil
idle_timer_ += delta_time;
// Solo contar tiempo para flips si:
// - NO está en modo LOGO, O
// - Está en modo LOGO Y ha alcanzado umbral de convergencia (80%)
bool can_start_flip = !is_logo_mode_ || convergence_threshold_reached_;
if (can_start_flip) {
idle_timer_ += delta_time;
}
// Pivoteo sutil constante (movimiento orgánico)
tilt_x_ += 0.4f * delta_time; // Velocidad sutil en X
@@ -308,6 +316,12 @@ void PNGShape::update(float delta_time, float screen_width, float screen_height)
angle_y_ = 0.0f;
}
}
// Detectar transición de flip (de true a false) para incrementar contador
if (was_flipping_last_frame_ && !is_flipping_) {
flip_count_++; // Flip completado
}
was_flipping_last_frame_ = is_flipping_;
}
void PNGShape::getPoint3D(int index, float& x, float& y, float& z) const {
@@ -387,3 +401,31 @@ float PNGShape::getScaleFactor(float screen_height) const {
// Escala dinámica según resolución
return PNG_SIZE_FACTOR;
}
// Sistema de convergencia: notificar a la figura sobre el % de pelotas en posición
void PNGShape::setConvergence(float convergence) {
current_convergence_ = convergence;
// Umbral de convergencia
constexpr float CONVERGENCE_THRESHOLD = 0.4f;
// Activar threshold cuando convergencia supera el umbral
if (!convergence_threshold_reached_ && convergence >= CONVERGENCE_THRESHOLD) {
convergence_threshold_reached_ = true;
}
// Desactivar threshold cuando convergencia cae por debajo del umbral
if (convergence < CONVERGENCE_THRESHOLD) {
convergence_threshold_reached_ = false;
}
}
// Obtener progreso del flip actual (0.0 = inicio del flip, 1.0 = fin del flip)
float PNGShape::getFlipProgress() const {
if (!is_flipping_) {
return 0.0f; // No está flipping, progreso = 0
}
// Calcular progreso normalizado (0.0 - 1.0)
return flip_timer_ / PNG_FLIP_DURATION;
}

View File

@@ -43,6 +43,14 @@ private:
// Modo LOGO (intervalos de flip más largos)
bool is_logo_mode_ = false; // true = usar intervalos LOGO (más lentos)
// Sistema de convergencia (solo relevante en modo LOGO)
float current_convergence_ = 0.0f; // Porcentaje actual de convergencia (0.0-1.0)
bool convergence_threshold_reached_ = false; // true si ha alcanzado umbral mínimo (80%)
// Sistema de tracking de flips (para modo LOGO - espera de flips)
int flip_count_ = 0; // Contador de flips completados (reset al entrar a LOGO)
bool was_flipping_last_frame_ = false; // Estado previo para detectar transiciones
// Dimensiones normalizadas
float scale_factor_ = 1.0f;
float center_offset_x_ = 0.0f;
@@ -70,6 +78,18 @@ public:
const char* getName() const override { return "PNG SHAPE"; }
float getScaleFactor(float screen_height) const override;
// Consultar estado de flip
bool isFlipping() const { return is_flipping_; }
// Obtener progreso del flip actual (0.0 = inicio, 1.0 = fin)
float getFlipProgress() const;
// Obtener número de flips completados (para modo LOGO)
int getFlipCount() const { return flip_count_; }
// Resetear contador de flips (llamar al entrar a LOGO MODE)
void resetFlipCount() { flip_count_ = 0; was_flipping_last_frame_ = false; }
// Control de modo LOGO (flip intervals más largos)
void setLogoMode(bool enable) {
is_logo_mode_ = enable;
@@ -78,4 +98,7 @@ public:
float idle_max = enable ? PNG_IDLE_TIME_MAX_LOGO : PNG_IDLE_TIME_MAX;
next_idle_time_ = idle_min + (rand() % 1000) / 1000.0f * (idle_max - idle_min);
}
// Sistema de convergencia (override de Shape::setConvergence)
void setConvergence(float convergence) override;
};

View File

@@ -27,4 +27,9 @@ public:
// screen_height: altura actual de pantalla
// Retorna: factor multiplicador para constantes de física (spring_k, damping, etc.)
virtual float getScaleFactor(float screen_height) const = 0;
// Notificar a la figura sobre el porcentaje de convergencia (pelotas cerca del objetivo)
// convergence: valor de 0.0 (0%) a 1.0 (100%) indicando cuántas pelotas están en posición
// Default: no-op (la mayoría de figuras no necesitan esta información)
virtual void setConvergence(float convergence) {}
};