**1. Bordes como obstáculos (no más wrapping):** - Implementada fuerza de repulsión cuando boids se acercan a bordes - Nueva regla: Boundary Avoidance (evitar bordes) - Fuerza proporcional a cercanía (0% en margen, 100% en colisión) - Constantes: BOID_BOUNDARY_MARGIN (50px), BOID_BOUNDARY_WEIGHT (7200 px/s²) **2. Variables ajustables en runtime:** - Añadidas 11 variables miembro en BoidManager (inicializadas con defines.h) - Permite modificar comportamiento sin recompilar - Variables: radios (separation/alignment/cohesion), weights, speeds, boundary - Base para futuras herramientas de debug/tweaking visual **3. Fix tecla G (BOIDS → PHYSICS):** - Corregido: toggleBoidsMode() ahora acepta parámetro force_gravity_on - handleGravityToggle() pasa explícitamente false para preservar inercia - Transición BOIDS→PHYSICS ahora mantiene gravedad OFF correctamente **Implementación:** - defines.h: +2 constantes (BOUNDARY_MARGIN, BOUNDARY_WEIGHT) - boid_manager.h: +11 variables miembro ajustables - boid_manager.cpp: - Constructor inicializa variables - Todas las funciones usan variables en lugar de constantes - applyBoundaries() completamente reescrito (repulsión vs wrapping) - engine.h/cpp: toggleBoidsMode() con parámetro opcional 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
127 lines
4.6 KiB
C++
127 lines
4.6 KiB
C++
#pragma once
|
|
|
|
#include <cstddef> // for size_t
|
|
|
|
#include "../defines.h" // for SimulationMode, AppMode
|
|
#include "../spatial_grid.h" // for SpatialGrid
|
|
|
|
// Forward declarations
|
|
class Engine;
|
|
class SceneManager;
|
|
class UIManager;
|
|
class StateManager;
|
|
class Ball;
|
|
|
|
/**
|
|
* @class BoidManager
|
|
* @brief Gestiona el comportamiento de enjambre (boids)
|
|
*
|
|
* Responsabilidad única: Implementación de algoritmo de boids (Reynolds 1987)
|
|
*
|
|
* Características:
|
|
* - Separación: Evitar colisiones con vecinos cercanos
|
|
* - Alineación: Seguir dirección promedio del grupo
|
|
* - Cohesión: Moverse hacia el centro de masa del grupo
|
|
* - Comportamiento emergente sin control centralizado
|
|
* - Física de steering behavior (velocidad limitada)
|
|
*/
|
|
class BoidManager {
|
|
public:
|
|
/**
|
|
* @brief Constructor
|
|
*/
|
|
BoidManager();
|
|
|
|
/**
|
|
* @brief Destructor
|
|
*/
|
|
~BoidManager();
|
|
|
|
/**
|
|
* @brief Inicializa el BoidManager con referencias a componentes del Engine
|
|
* @param engine Puntero al Engine (para acceso a recursos)
|
|
* @param scene_mgr Puntero a SceneManager (acceso a bolas)
|
|
* @param ui_mgr Puntero a UIManager (notificaciones)
|
|
* @param state_mgr Puntero a StateManager (estados de aplicación)
|
|
* @param screen_width Ancho de pantalla actual
|
|
* @param screen_height Alto de pantalla actual
|
|
*/
|
|
void initialize(Engine* engine, SceneManager* scene_mgr, UIManager* ui_mgr,
|
|
StateManager* state_mgr, int screen_width, int screen_height);
|
|
|
|
/**
|
|
* @brief Actualiza el tamaño de pantalla (llamado en resize/fullscreen)
|
|
* @param width Nuevo ancho de pantalla
|
|
* @param height Nuevo alto de pantalla
|
|
*/
|
|
void updateScreenSize(int width, int height);
|
|
|
|
/**
|
|
* @brief Activa el modo boids
|
|
*/
|
|
void activateBoids();
|
|
|
|
/**
|
|
* @brief Desactiva el modo boids (vuelve a física normal)
|
|
* @param force_gravity_on Si debe forzar gravedad ON al salir
|
|
*/
|
|
void deactivateBoids(bool force_gravity_on = true);
|
|
|
|
/**
|
|
* @brief Toggle entre modo boids y modo física
|
|
* @param force_gravity_on Si debe forzar gravedad ON al salir de boids
|
|
*/
|
|
void toggleBoidsMode(bool force_gravity_on = true);
|
|
|
|
/**
|
|
* @brief Actualiza el comportamiento de todas las bolas como boids
|
|
* @param delta_time Delta time para física
|
|
*/
|
|
void update(float delta_time);
|
|
|
|
/**
|
|
* @brief Verifica si el modo boids está activo
|
|
* @return true si modo boids está activo
|
|
*/
|
|
bool isBoidsActive() const { return boids_active_; }
|
|
|
|
private:
|
|
// Referencias a componentes del Engine
|
|
Engine* engine_;
|
|
SceneManager* scene_mgr_;
|
|
UIManager* ui_mgr_;
|
|
StateManager* state_mgr_;
|
|
|
|
// Tamaño de pantalla
|
|
int screen_width_;
|
|
int screen_height_;
|
|
|
|
// Estado del modo boids
|
|
bool boids_active_;
|
|
|
|
// Spatial Hash Grid para optimización O(n²) → O(n)
|
|
// FASE 2: Grid reutilizable para búsquedas de vecinos
|
|
SpatialGrid spatial_grid_;
|
|
|
|
// === Parámetros ajustables en runtime (inicializados con valores de defines.h) ===
|
|
// Permite modificar comportamiento sin recompilar (para tweaking/debug visual)
|
|
float separation_radius_; // Radio de separación (evitar colisiones)
|
|
float alignment_radius_; // Radio de alineación (matching de velocidad)
|
|
float cohesion_radius_; // Radio de cohesión (centro de masa)
|
|
float separation_weight_; // Peso fuerza de separación (aceleración px/s²)
|
|
float alignment_weight_; // Peso fuerza de alineación (steering proporcional)
|
|
float cohesion_weight_; // Peso fuerza de cohesión (aceleración px/s²)
|
|
float max_speed_; // Velocidad máxima (px/s)
|
|
float min_speed_; // Velocidad mínima (px/s)
|
|
float max_force_; // Fuerza máxima de steering (px/s)
|
|
float boundary_margin_; // Margen para repulsión de bordes (px)
|
|
float boundary_weight_; // Peso fuerza de repulsión de bordes (aceleración px/s²)
|
|
|
|
// Métodos privados para las reglas de Reynolds
|
|
void applySeparation(Ball* boid, float delta_time);
|
|
void applyAlignment(Ball* boid, float delta_time);
|
|
void applyCohesion(Ball* boid, float delta_time);
|
|
void applyBoundaries(Ball* boid); // Repulsión de bordes (ya no wrapping)
|
|
void limitSpeed(Ball* boid); // Limitar velocidad máxima
|
|
};
|