#pragma once #include // for unique_ptr, shared_ptr #include // for vector #include "ball.hpp" // for Ball #include "defines.hpp" // for GravityDirection // Forward declarations class Texture; class ThemeManager; /** * @class SceneManager * @brief Gestiona toda la lógica de creación, física y actualización de bolas * * Responsabilidad única: Manejo de la escena (bolas, gravedad, física) * * Características: * - Crea y destruye bolas según escenario seleccionado * - Controla la dirección y estado de la gravedad * - Actualiza física de todas las bolas cada frame * - Proporciona acceso controlado a las bolas para rendering * - Mantiene el Engine desacoplado de la lógica de física */ class SceneManager { public: /** * @brief Constructor * @param screen_width Ancho lógico de la pantalla * @param screen_height Alto lógico de la pantalla */ SceneManager(int screen_width, int screen_height); /** * @brief Inicializa el manager con configuración inicial * @param scenario Escenario inicial (índice de BALL_COUNT_SCENARIOS) * @param texture Textura compartida para sprites de bolas * @param theme_manager Puntero al gestor de temas (para colores) */ void initialize(int scenario, std::shared_ptr texture, ThemeManager* theme_manager); /** * @brief Actualiza física de todas las bolas * @param delta_time Tiempo transcurrido desde último frame (segundos) */ void update(float delta_time); // === Gestión de bolas === /** * @brief Cambia el número de bolas según escenario * @param scenario_id Índice del escenario (0-7 para 10 a 50,000 bolas) * @param mode Modo de simulación actual (afecta inicialización) */ void changeScenario(int scenario_id, SimulationMode mode); /** * @brief Actualiza textura y tamaño de todas las bolas * @param new_texture Nueva textura compartida * @param new_ball_size Nuevo tamaño de bolas (píxeles) */ void updateBallTexture(std::shared_ptr new_texture, int new_ball_size); // === Control de gravedad === /** * @brief Aplica impulso a todas las bolas alejándolas de la superficie de gravedad */ void pushBallsAwayFromGravity(); /** * @brief Alterna el estado de gravedad (ON/OFF) en todas las bolas */ void switchBallsGravity(); /** * @brief Reactiva gravedad solo si estaba desactivada */ void enableBallsGravityIfDisabled(); /** * @brief Fuerza gravedad ON en todas las bolas */ void forceBallsGravityOn(); /** * @brief Fuerza gravedad OFF en todas las bolas (con impulso si >50% en superficie) */ void forceBallsGravityOff(); /** * @brief Cambia la dirección de la gravedad * @param direction Nueva dirección (UP/DOWN/LEFT/RIGHT) */ void changeGravityDirection(GravityDirection direction); // === Acceso a datos (read-only) === /** * @brief Obtiene referencia constante al vector de bolas (para rendering) */ const std::vector>& getBalls() const { return balls_; } /** * @brief Obtiene referencia mutable al vector de bolas (para ShapeManager) * NOTA: Usar con cuidado, solo para sistemas que necesitan modificar estado de bolas */ std::vector>& getBallsMutable() { return balls_; } /** * @brief Obtiene número total de bolas */ size_t getBallCount() const { return balls_.size(); } /** * @brief Verifica si hay al menos una bola */ bool hasBalls() const { return !balls_.empty(); } /** * @brief Obtiene puntero a la primera bola (para debug info) * @return Puntero constante o nullptr si no hay bolas */ const Ball* getFirstBall() const { return balls_.empty() ? nullptr : balls_[0].get(); } /** * @brief Obtiene dirección actual de gravedad */ GravityDirection getCurrentGravity() const { return current_gravity_; } /** * @brief Obtiene escenario actual */ int getCurrentScenario() const { return scenario_; } /** * @brief Actualiza resolución de pantalla (para resize/fullscreen) * @param width Nuevo ancho lógico * @param height Nuevo alto lógico */ void updateScreenSize(int width, int height); private: // === Datos de escena === std::vector> balls_; GravityDirection current_gravity_; int scenario_; // === Configuración de pantalla === int screen_width_; int screen_height_; int current_ball_size_; // === Referencias a otros sistemas (no owned) === std::shared_ptr texture_; ThemeManager* theme_manager_; // === Métodos privados auxiliares === /** * @brief Ajusta posiciones de bolas al cambiar tamaño de sprite * @param old_size Tamaño anterior * @param new_size Tamaño nuevo */ void updateBallSizes(int old_size, int new_size); };