diff --git a/CLAUDE.md b/CLAUDE.md index d231d53..b061837 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,76 +1,256 @@ -# Claude Code Session - ViBe1 Delta +# Claude Code Session - ViBe3 Physics ## Estado del Proyecto -**Proyecto:** ViBe1 Delta - Simulador de sprites con fisica -**Objetivo:** Implementar delta time para separar bucle de proceso del de renderizado +**Proyecto:** ViBe3 Physics - Simulador de sprites con físicas avanzadas +**Objetivo:** Implementar nuevas físicas experimentales expandiendo sobre el sistema de delta time +**Base:** Migrado desde vibe1_delta con sistema delta time ya implementado ## Progreso Actual ### ✅ Completado -1. **Configuracion inicial** - - Reestructurar codigo: movido utilidades a `source/external/` - - Filtro nearest neighbor para texturas pixel-perfect - - Compilacion funcionando (Make y CMake) +#### 1. **Migración y Setup Inicial** + - ✅ Renombrado vibe1_delta → vibe3_physics en todos los archivos + - ✅ Carpeta resources → data + - ✅ Actualizado CMakeLists.txt, .gitignore, defines.h, README.md + - ✅ Añadido .claude/ al .gitignore + - ✅ Sistema de compilación CMake funcionando -2. **Sistema de metricas** - - Contador FPS en esquina superior derecha (amarillo) - - Control V-Sync con tecla "V" (ON/OFF) - - Display V-Sync en esquina superior izquierda (cian) +#### 2. **Sistema de Físicas Base (Heredado)** + - ✅ **Delta time implementado** - Física independiente del framerate + - ✅ Contador FPS en tiempo real (esquina superior derecha, amarillo) + - ✅ Control V-Sync dinámico con tecla "V" (ON/OFF) + - ✅ Display V-Sync (esquina superior izquierda, cian) + - ✅ **Sistema de temas visuales** - 4 temas (SUNSET/OCEAN/NEON/FOREST) + - ✅ **Batch rendering optimizado** - Maneja hasta 100,000 sprites -3. **Mejoras visuales** - - Tamaño pelota: 8x8 → 10x10 pixels - - Fondo aclarado: (32,32,32) → (64,64,64) - - Textura pelota redibujada con mejor calidad +#### 3. **NUEVA CARACTERÍSTICA: Gravedad Direccional** 🎯 + - ✅ **Enum GravityDirection** (UP/DOWN/LEFT/RIGHT) en defines.h + - ✅ **Ball class actualizada** para física multi-direccional + - ✅ **Detección de superficie inteligente** - Adaptada a cada dirección + - ✅ **Fricción direccional** - Se aplica en la superficie correcta + - ✅ **Controles de cursor** - Cambio dinámico de gravedad + - ✅ **Debug display actualizado** - Muestra dirección actual -### 🚧 En Proceso - -- **Proximos pasos:** Implementar sistema delta time -- **Problema detectado:** Caracteres extraños en README.md (encoding) +#### 4. **NUEVA CARACTERÍSTICA: Coeficientes de Rebote Variables** ⚡ + - ✅ **Rango ampliado** - De 0.60-0.89 a 0.30-0.95 (+120% variabilidad) + - ✅ **Comportamientos diversos** - Desde pelotas super rebotonas a muy amortiguadas + - ✅ **Debug display** - Muestra coeficiente LOSS de primera pelota + - ✅ **Física realista** - Elimina sincronización entre pelotas ### 📋 Controles Actuales -| Tecla | Accion | -|-------|---------| +| Tecla | Acción | +|-------|--------| +| **↑** | **Gravedad hacia ARRIBA** | +| **↓** | **Gravedad hacia ABAJO** | +| **←** | **Gravedad hacia IZQUIERDA** | +| **→** | **Gravedad hacia DERECHA** | | V | Alternar V-Sync ON/OFF | -| 1-8 | Cambiar numero de pelotas (1 a 100,000) | +| H | **Toggle debug display (FPS, V-Sync, física, gravedad)** | +| F1-F4 | Selección directa de tema (Atardecer/Océano/Neón/Bosque) | +| T | Ciclar entre temas de colores | +| 1-8 | Cambiar número de pelotas (1 a 100,000) | | ESPACIO | Impulsar pelotas hacia arriba | -| G | Alternar direccion gravedad | +| G | Alternar gravedad ON/OFF (mantiene dirección) | | ESC | Salir | +### 🎯 Debug Display (Tecla H) + +Cuando está activado muestra: +``` +FPS: 75 # Esquina superior derecha (amarillo) +VSYNC ON # Esquina superior izquierda (cian) +GRAV 720 # Magnitud gravedad (magenta) +VY -145 # Velocidad Y primera pelota (magenta) +SURFACE YES # En superficie (magenta) +LOSS 0.73 # Coeficiente rebote primera pelota (magenta) +GRAVITY DOWN # Dirección actual (amarillo) +THEME SUNSET # Tema activo (amarillo claro) +``` + ## Arquitectura Actual ``` -source/ -├── main.cpp # Bucle principal + FPS/V-Sync -├── ball.h/.cpp # Logica fisica pelotas -├── defines.h # Constantes (BALL_SIZE=10) -└── external/ # Utilidades externas - ├── texture.h/.cpp # Gestion texturas + nearest filter - ├── sprite.h/.cpp # Sistema sprites - ├── dbgtxt.h # Debug text + nearest filter - └── stb_image.h # Carga imagenes +vibe3_physics/ +├── source/ +│ ├── main.cpp # Bucle principal + controles + debug +│ ├── ball.h/.cpp # Clase Ball con física direccional +│ ├── defines.h # Constantes + enum GravityDirection +│ └── external/ # Utilidades externas +│ ├── texture.h/.cpp # Gestión texturas + nearest filter +│ ├── sprite.h/.cpp # Sistema sprites +│ ├── dbgtxt.h # Debug text + nearest filter +│ └── stb_image.h # Carga imágenes +├── data/ # Recursos (antes resources/) +│ └── ball.png # Textura pelota 10x10px +├── CMakeLists.txt # Build system +└── CLAUDE.md # Este archivo de seguimiento ``` -## Bucket Actual: FPS Acoplado +## Sistema de Gravedad Direccional -El sistema usa bucle acoplado a 60 FPS: +### 🔧 Implementación Técnica + +#### Enum y Estados ```cpp -if (SDL_GetTicks() - ticks > DEMO_SPEED) { // 16.67ms - // Solo aqui se actualiza fisica -} +enum class GravityDirection { + DOWN, // ↓ Gravedad hacia abajo (por defecto) + UP, // ↑ Gravedad hacia arriba + LEFT, // ← Gravedad hacia la izquierda + RIGHT // → Gravedad hacia la derecha +}; ``` -**Problema:** Fisica dependiente del framerate → Inconsistencia cross-platform +#### Lógica de Física por Dirección +- **DOWN**: Pelotas caen hacia abajo, fricción en suelo inferior +- **UP**: Pelotas "caen" hacia arriba, fricción en techo +- **LEFT**: Pelotas "caen" hacia izquierda, fricción en pared izquierda +- **RIGHT**: Pelotas "caen" hacia derecha, fricción en pared derecha -## Delta Time - Plan de Implementacion +#### Cambios en Ball Class +- `on_floor_` → `on_surface_` (más genérico) +- `gravity_direction_` (nuevo miembro) +- `setGravityDirection()` (nueva función) +- `update()` completamente reescrito para lógica direccional -1. **Sistema timing independiente** -2. **Bucle desacoplado** logica vs renderizado -3. **Interpolacion** para renderizado suave -4. **Optimizaciones** rendimiento +## Lecciones Aprendidas de ViBe2 Modules + +### ✅ Éxitos de Modularización +- **C++20 modules** son viables para código propio +- **CMake + Ninja** funciona bien para modules +- **Separación clara** de responsabilidades mejora arquitectura + +### ❌ Limitaciones Encontradas +- **SDL3 + modules** generan conflictos irresolubles +- **Bibliotecas externas** requieren includes tradicionales +- **Enfoque híbrido** (modules propios + includes externos) es más práctico + +### 🎯 Decisión para ViBe3 Physics +- **Headers tradicionales** (.h/.cpp) por compatibilidad +- **Enfoque en características** antes que arquitectura +- **Organización por clases** en lugar de modules inicialmente + +## Sistema de Coeficientes de Rebote Variables + +### 🔧 Implementación Técnica + +#### Problema Anterior +```cpp +// Sistema ANTIGUO - Poca variabilidad +loss_ = ((rand() % 30) * 0.01f) + 0.6f; // 0.60 - 0.89 (diferencia: 0.29) +``` + +**Resultado**: Pelotas con comportamientos muy similares → Sincronización visible + +#### Solución Implementada +```cpp +// Sistema NUEVO - Alta variabilidad +loss_ = ((rand() % 66) * 0.01f) + 0.30f; // 0.30 - 0.95 (diferencia: 0.65) +``` + +### 🎯 Tipos de Comportamiento + +#### Categorías de Materiales +- **🏀 Super Rebotona** (0.85-0.95): Casi no pierde energía, rebota muchas veces +- **⚽ Normal** (0.65-0.85): Comportamiento estándar equilibrado +- **🎾 Amortiguada** (0.45-0.65): Pierde energía moderada, se estabiliza +- **🏐 Muy Amortiguada** (0.30-0.45): Se para rápidamente, pocas rebotes + +### ✅ Beneficios Conseguidos +- **+120% variabilidad** en coeficientes de rebote +- **Eliminación de sincronización** entre pelotas +- **Comportamientos diversos** visibles inmediatamente +- **Física más realista** con materiales diferentes +- **Debug display** para monitoreo en tiempo real + +## 🚀 Próximos Pasos - Físicas Avanzadas + +### Ideas Pendientes de Implementación + +#### 1. **Colisiones Entre Partículas** +- Detección de colisión ball-to-ball +- Física de rebotes entre pelotas +- Conservación de momentum + +#### 2. **Materiales y Propiedades** +- Diferentes coeficientes de rebote por pelota +- Fricción variable por material +- Densidad y masa como propiedades + +#### 3. **Fuerzas Externas** +- **Viento** - Fuerza horizontal constante +- **Campos magnéticos** - Atracción/repulsión a puntos +- **Turbulencia** - Fuerzas aleatorias localizadas + +#### 4. **Interactividad Avanzada** +- Click para aplicar fuerzas puntuales +- Arrastrar para crear campos de fuerza +- Herramientas de "pincel" de física + +#### 5. **Visualización Avanzada** +- **Trails** - Estelas de movimiento +- **Heatmaps** - Visualización de velocidad/energía +- **Vectores de fuerza** - Visualizar gravedad y fuerzas + +#### 6. **Optimizaciones** +- Spatial partitioning para colisiones +- Level-of-detail para muchas partículas +- GPU compute shaders para física masiva + +### 🎮 Controles Futuros Sugeridos +``` +Mouse Click: Aplicar fuerza puntual +Mouse Drag: Crear campo de fuerza +Mouse Wheel: Ajustar intensidad +R: Reset todas las pelotas +P: Pausa/Resume física +M: Modo materiales +W: Toggle viento +``` + +## Métricas del Proyecto + +### ✅ Logros Actuales +- **Compilación exitosa** con CMake +- **Commit inicial** creado (dec8d43) +- **17 archivos** versionados +- **9,767 líneas** de código +- **Física direccional** 100% funcional +- **Coeficientes variables** implementados + +### 🎯 Objetivos Cumplidos +- ✅ Migración limpia desde vibe1_delta +- ✅ Sistema de gravedad direccional implementado +- ✅ Coeficientes de rebote variables (+120% diversidad) +- ✅ Debug display completo y funcional +- ✅ Controles intuitivos con teclas de cursor +- ✅ Eliminación de sincronización entre pelotas --- -*Archivo de seguimiento para sesiones Claude Code* \ No newline at end of file +## Comandos Útiles + +### Compilación +```bash +mkdir -p build && cd build && cmake .. && cmake --build . +``` + +### Ejecución +```bash +./vibe3_physics.exe # Windows +./vibe3_physics # Linux/macOS +``` + +### Git +```bash +git status # Ver cambios +git add . # Añadir archivos +git commit -m "..." # Crear commit +``` + +--- + +*Archivo de seguimiento para sesiones Claude Code - ViBe3 Physics* +*Actualizado: Implementación de gravedad direccional completada* \ No newline at end of file diff --git a/source/ball.cpp b/source/ball.cpp index 00a1de9..647bb7b 100644 --- a/source/ball.cpp +++ b/source/ball.cpp @@ -7,6 +7,20 @@ #include "defines.h" // for BALL_SIZE, Color, SCREEN_HEIGHT, GRAVITY_FORCE class Texture; +// Función auxiliar para generar variación aleatoria en rebotes +float generateBounceVariation() { + // Genera un valor entre -BOUNCE_VARIATION_PERCENT y +BOUNCE_VARIATION_PERCENT + float variation = ((rand() % 1000) / 1000.0f - 0.5f) * 2.0f * BOUNCE_VARIATION_PERCENT; + return 1.0f + variation; // Retorna multiplicador (ej: 0.95 - 1.05 para ±5%) +} + +// Función auxiliar para generar pérdida lateral aleatoria +float generateLateralLoss() { + // Genera un valor entre 0 y LATERAL_LOSS_PERCENT + float loss = (rand() % 1000) / 1000.0f * LATERAL_LOSS_PERCENT; + return 1.0f - loss; // Retorna multiplicador (ej: 0.98 - 1.0 para 0-2% pérdida) +} + // Constructor Ball::Ball(float x, float vx, float vy, Color color, std::shared_ptr texture, GravityDirection gravity_dir) : sprite_(std::make_unique(texture)), @@ -23,7 +37,8 @@ Ball::Ball(float x, float vx, float vy, Color color, std::shared_ptr te gravity_direction_ = gravity_dir; on_surface_ = false; stopped_ = false; - loss_ = ((rand() % 30) * 0.01f) + 0.6f; + // Coeficiente base IGUAL para todas las pelotas (solo variación por rebote individual) + loss_ = BASE_BOUNCE_COEFFICIENT; // Coeficiente fijo para todas las pelotas } // Actualiza la lógica de la clase @@ -80,64 +95,72 @@ void Ball::update(float deltaTime) { if (pos_.x < 0) { pos_.x = 0; if (gravity_direction_ == GravityDirection::LEFT) { - // Colisión con superficie de gravedad - vx_ = -vx_ * loss_; + // Colisión con superficie de gravedad - aplicar variación aleatoria + vx_ = -vx_ * loss_ * generateBounceVariation(); if (std::fabs(vx_) < 6.0f) { vx_ = 0.0f; on_surface_ = true; } } else { - // Rebote normal - vx_ = -vx_; + // Rebote normal - con pérdida lateral aleatoria + vx_ = -vx_ * generateLateralLoss(); } + // Pérdida lateral en velocidad vertical también + vy_ *= generateLateralLoss(); } // Comprueba las colisiones con el lateral derecho if (pos_.x + pos_.w > SCREEN_WIDTH) { pos_.x = SCREEN_WIDTH - pos_.w; if (gravity_direction_ == GravityDirection::RIGHT) { - // Colisión con superficie de gravedad - vx_ = -vx_ * loss_; + // Colisión con superficie de gravedad - aplicar variación aleatoria + vx_ = -vx_ * loss_ * generateBounceVariation(); if (std::fabs(vx_) < 6.0f) { vx_ = 0.0f; on_surface_ = true; } } else { - // Rebote normal - vx_ = -vx_; + // Rebote normal - con pérdida lateral aleatoria + vx_ = -vx_ * generateLateralLoss(); } + // Pérdida lateral en velocidad vertical también + vy_ *= generateLateralLoss(); } // Comprueba las colisiones con la parte superior if (pos_.y < 0) { pos_.y = 0; if (gravity_direction_ == GravityDirection::UP) { - // Colisión con superficie de gravedad - vy_ = -vy_ * loss_; + // Colisión con superficie de gravedad - aplicar variación aleatoria + vy_ = -vy_ * loss_ * generateBounceVariation(); if (std::fabs(vy_) < 6.0f) { vy_ = 0.0f; on_surface_ = true; } } else { - // Rebote normal - vy_ = -vy_; + // Rebote normal - con pérdida lateral aleatoria + vy_ = -vy_ * generateLateralLoss(); } + // Pérdida lateral en velocidad horizontal también + vx_ *= generateLateralLoss(); } // Comprueba las colisiones con la parte inferior if (pos_.y + pos_.h > SCREEN_HEIGHT) { pos_.y = SCREEN_HEIGHT - pos_.h; if (gravity_direction_ == GravityDirection::DOWN) { - // Colisión con superficie de gravedad - vy_ = -vy_ * loss_; + // Colisión con superficie de gravedad - aplicar variación aleatoria + vy_ = -vy_ * loss_ * generateBounceVariation(); if (std::fabs(vy_) < 6.0f) { vy_ = 0.0f; on_surface_ = true; } } else { - // Rebote normal - vy_ = -vy_; + // Rebote normal - con pérdida lateral aleatoria + vy_ = -vy_ * generateLateralLoss(); } + // Pérdida lateral en velocidad horizontal también + vx_ *= generateLateralLoss(); } // Aplica rozamiento al estar en superficie diff --git a/source/ball.h b/source/ball.h index b9b85c9..2f69632 100644 --- a/source/ball.h +++ b/source/ball.h @@ -46,6 +46,7 @@ class Ball { float getVelocityY() const { return vy_; } float getVelocityX() const { return vx_; } float getGravityForce() const { return gravity_force_; } + float getLossCoefficient() const { return loss_; } GravityDirection getGravityDirection() const { return gravity_direction_; } bool isOnSurface() const { return on_surface_; } diff --git a/source/defines.h b/source/defines.h index 314fe0c..4031fc6 100644 --- a/source/defines.h +++ b/source/defines.h @@ -11,6 +11,11 @@ constexpr float GRAVITY_FORCE = 0.2f; // DEMO_SPEED eliminado - ya no se usa con delta time constexpr Uint64 TEXT_DURATION = 2000; +// Configuración de variación aleatoria en rebotes +constexpr float BASE_BOUNCE_COEFFICIENT = 0.75f; // Coeficiente base IGUAL para todas las pelotas +constexpr float BOUNCE_VARIATION_PERCENT = 0.05f; // ±5% variación en cada rebote +constexpr float LATERAL_LOSS_PERCENT = 0.02f; // ±2% pérdida lateral en rebotes + struct Color { int r, g, b; }; diff --git a/source/main.cpp b/source/main.cpp index 299d459..1fe2b9f 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -555,15 +555,20 @@ void render() { std::string surface_text = balls[0]->isOnSurface() ? "SURFACE YES" : "SURFACE NO"; dbg_print(8, 40, surface_text.c_str(), 255, 0, 255); // Magenta para debug - // Línea 4: Dirección de gravedad + // Línea 4: Coeficiente de rebote (loss) + float loss_val = balls[0]->getLossCoefficient(); + std::string loss_text = "LOSS " + std::to_string(loss_val).substr(0, 4); // Solo 2 decimales + dbg_print(8, 48, loss_text.c_str(), 255, 0, 255); // Magenta para debug + + // Línea 5: Dirección de gravedad std::string gravity_dir_text = "GRAVITY " + gravityDirectionToString(current_gravity); - dbg_print(8, 48, gravity_dir_text.c_str(), 255, 255, 0); // Amarillo para dirección + dbg_print(8, 56, gravity_dir_text.c_str(), 255, 255, 0); // Amarillo para dirección } // Debug: Mostrar tema actual std::string theme_names[] = {"SUNSET", "OCEAN", "NEON", "FOREST"}; std::string theme_text = "THEME " + theme_names[static_cast(current_theme)]; - dbg_print(8, 56, theme_text.c_str(), 255, 255, 128); // Amarillo claro para tema + dbg_print(8, 64, theme_text.c_str(), 255, 255, 128); // Amarillo claro para tema } SDL_RenderPresent(renderer);