- Añadir tecla H para activar/desactivar debug display - Debug display desactivado por defecto para interfaz limpia - Implementar procesamiento bitmap monocromo a RGBA32 con transparencia - Convertir fondo blanco original a pixels transparentes - Convertir texto negro original a pixels blancos para color mod - Configurar SDL_BLENDMODE_BLEND para transparencia correcta - Actualizar README con documentacion de tecla H y debug display - Conseguir texto flotante sin fondo negro para mejor legibilidad 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
9.1 KiB
ViBe1 Delta - Simulador de Sprites con Fisica
ViBe1 Delta es un programa de demostracion que utiliza SDL3 para mostrar sprites (pelotas) rebotando en pantalla con simulacion de fisica basica. Este proyecto sirve como base para experimentar con bucles de juego, renderizado y fisica en tiempo real.
🎯 Caracteristicas Actuales
- Simulacion de fisica: Gravedad, rebotes y colisiones con perdida de energia
- Multiples escenarios: 8 configuraciones predefinidas (1 a 100,000 pelotas)
- Interactividad: Controles de teclado para modificar el comportamiento
- Renderizado eficiente: Uso de SDL3 con escalado logico
- Colores aleatorios: Cada pelota tiene un color unico generado proceduralmente
- Monitor de rendimiento: Contador FPS en tiempo real
- Control V-Sync: Activacion/desactivacion dinamica del V-Sync
🎮 Controles
| Tecla | Accion |
|---|---|
H |
Alternar debug display (FPS, V-Sync, valores fisica) |
V |
Alternar V-Sync ON/OFF |
1-8 |
Cambiar numero de pelotas (1, 10, 100, 500, 1K, 10K, 50K, 100K) |
ESPACIO |
Impulsar todas las pelotas hacia arriba |
G |
Alternar direccion de la gravedad |
ESC |
Salir del programa |
📊 Informacion en Pantalla
- Centro: Numero de pelotas activas en blanco (temporal)
Debug Display (Tecla H)
Cuando se activa el debug display con la tecla H:
- Esquina superior izquierda: Estado V-Sync (VSYNC: ON/OFF) en cian
- Esquina superior derecha: Contador FPS en tiempo real en amarillo
- Linea 3: Valores fisica primera pelota (GRAV, VY, FLOOR) en magenta
🏗️ Estructura del Proyecto
vibe_delta/
├── source/
│ ├── main.cpp # Bucle principal y logica del juego
│ ├── ball.h/cpp # Clase Ball - logica de las pelotas
│ ├── defines.h # Constantes y configuracion
│ └── external/ # Utilidades y bibliotecas externas
│ ├── sprite.h/cpp # Clase Sprite - renderizado de texturas
│ ├── texture.h/cpp # Clase Texture - gestion de imagenes
│ ├── dbgtxt.h # Sistema de debug para texto en pantalla
│ └── stb_image.h # Biblioteca para cargar imagenes
├── resources/
│ └── ball.png # Textura de la pelota (10x10 pixeles)
├── CMakeLists.txt # Configuracion de CMake
├── Makefile # Configuracion de Make
├── CLAUDE.md # Seguimiento de desarrollo
└── .gitignore # Archivos ignorados por Git
🔧 Requisitos del Sistema
- SDL3 (Simple DirectMedia Layer 3)
- C++20 compatible compiler
- CMake 3.20+ o Make
- Plataforma: Windows, Linux, macOS
Instalacion de SDL3
Windows (MinGW)
# Usando vcpkg o compilar desde fuente
vcpkg install sdl3
Linux
# Ubuntu/Debian
sudo apt install libsdl3-dev
# Arch Linux
sudo pacman -S sdl3
macOS
brew install sdl3
🚀 Compilacion
Opcion 1: CMake (Recomendado)
mkdir build && cd build
cmake ..
make
Opcion 2: Make directo
make
▶️ Ejecucion
# Desde la raiz del proyecto
./vibe1_delta # Linux/macOS
./vibe1_delta.exe # Windows
📊 Detalles Tecnicos
Configuracion Actual
- Resolucion: 320x240 pixeles (escalado x3 = 960x720)
- Sistema de timing: Delta time independiente del framerate
- Fisica: Gravedad constante (0.2f), rebotes con perdida de energia
- Tamaño de pelota: 10x10 pixeles
- V-Sync: Activado por defecto, controlable dinamicamente
Arquitectura del Codigo
-
main.cpp: Contiene el bucle principal con cuatro fases:
calculateDeltaTime(): Calcula tiempo transcurrido entre framesupdate(): Actualiza la logica del juego usando delta time + calculo FPScheckEvents(): Procesa eventos de entradarender(): Renderiza la escena + overlays informativos
-
Ball: Maneja la fisica de cada pelota individual con timing basado en delta time
-
Sprite: Sistema de renderizado de texturas con filtro nearest neighbor
-
Texture: Gestion de carga y renderizado de imagenes con filtro pixel-perfect
✅ Migracion a Delta Time (COMPLETADO)
Sistema Anterior (Frame-Based)
El sistema original estaba acoplado a 60 FPS con logica dependiente del framerate:
// Sistema ANTIGUO en update()
if (SDL_GetTicks() - ticks > DEMO_SPEED) { // DEMO_SPEED = 1000/60 = 16.67ms
// Solo aqui se actualizaba la fisica cada 16.67ms
for (auto &ball : balls) {
ball->update(); // Sin parametros de tiempo
}
ticks = SDL_GetTicks();
}
Problemas del sistema anterior:
- Velocidad inconsistente entre diferentes refresh rates (60Hz vs 75Hz vs 144Hz)
- Logica de fisica acoplada a framerate fijo
- V-Sync ON/OFF cambiaba la velocidad del juego
- Rendimiento inconsistente en diferentes hardware
Sistema Actual (Delta Time)
Implementacion delta time para simulacion independiente del framerate:
// Sistema NUEVO - Variables globales
Uint64 last_frame_time = 0;
float delta_time = 0.0f;
// Calculo de delta time
void calculateDeltaTime() {
Uint64 current_time = SDL_GetTicks();
if (last_frame_time == 0) {
last_frame_time = current_time;
delta_time = 1.0f / 60.0f; // Primer frame a 60 FPS
return;
}
delta_time = (current_time - last_frame_time) / 1000.0f; // Convertir a segundos
last_frame_time = current_time;
// Limitar delta time para evitar saltos grandes
if (delta_time > 0.05f) {
delta_time = 1.0f / 60.0f; // Fallback a 60 FPS
}
}
// Bucle principal actualizado
while (!should_exit) {
calculateDeltaTime(); // 1. Calcular tiempo transcurrido
update(); // 2. Actualizar logica (usa delta_time)
checkEvents(); // 3. Procesar entrada
render(); // 4. Renderizar escena
}
Conversion de Fisica: Frame-Based → Time-Based
1. Conversion de Velocidades
// En Ball::Ball() constructor
// ANTES: velocidades en pixeles/frame
vx_ = vx;
vy_ = vy;
// AHORA: convertir a pixeles/segundo (x60)
vx_ = vx * 60.0f;
vy_ = vy * 60.0f;
2. Conversion de Gravedad (Aceleracion)
// En Ball::Ball() constructor
// ANTES: gravedad en pixeles/frame²
gravity_force_ = GRAVITY_FORCE;
// AHORA: convertir a pixeles/segundo² (x60²)
gravity_force_ = GRAVITY_FORCE * 60.0f * 60.0f; // 3600x multiplicador
¿Por que 60² para gravedad?
- Velocidad:
pixeles/frame * frame/segundo = pixeles/segundo→ x60 - Aceleracion:
pixeles/frame² * frame²/segundo² = pixeles/segundo²→ x60²
3. Aplicacion de Delta Time en Fisica
// En Ball::update(float deltaTime)
// ANTES: incrementos fijos por frame
vy_ += gravity_force_;
pos_.x += vx_;
pos_.y += vy_;
// AHORA: incrementos proporcionales al tiempo transcurrido
vy_ += gravity_force_ * deltaTime; // Aceleracion * tiempo
pos_.x += vx_ * deltaTime; // Velocidad * tiempo
pos_.y += vy_ * deltaTime;
Valores de Debug: Antes vs Ahora
| Parametro | Sistema Anterior | Sistema Delta Time | Razon |
|---|---|---|---|
| Velocidad X/Y | 1.0 - 3.0 pixeles/frame | 60.0 - 180.0 pixeles/segundo | x60 conversion |
| Gravedad | 0.2 pixeles/frame² | 720.0 pixeles/segundo² | x3600 conversion |
| Debug Display | No disponible | GRAV: 720.000000 VY: -140.5 FLOOR: NO | Valores en tiempo real |
Beneficios Conseguidos
- ✅ Velocidad consistente entre 60Hz, 75Hz, 144Hz y otros refresh rates
- ✅ V-Sync independiente: misma velocidad con V-Sync ON/OFF
- ✅ Fisica precisa: gravedad y movimiento calculados correctamente
- ✅ Escalabilidad: preparado para futuras optimizaciones
- ✅ Debug en tiempo real: monitoreo de valores de fisica
Sistema de Debug Implementado
// Debug display para primera pelota
if (!balls.empty()) {
std::string debug_text = "GRAV: " + std::to_string(balls[0]->getGravityForce()) +
" VY: " + std::to_string(balls[0]->getVelocityY()) +
" FLOOR: " + (balls[0]->isOnFloor() ? "YES" : "NO");
dbg_print(8, 24, debug_text.c_str(), 255, 0, 255); // Magenta
}
🛠️ Desarrollo
Para contribuir al proyecto:
- Fork del repositorio
- Crear rama de feature (
git checkout -b feature/nueva-caracteristica) - Commit de cambios (
git commit -am 'Añadir nueva caracteristica') - Push a la rama (
git push origin feature/nueva-caracteristica) - Crear Pull Request
📝 Notas Tecnicas
- El proyecto usa smart pointers (unique_ptr, shared_ptr) para gestion de memoria
- RAII para recursos SDL
- Separacion de responsabilidades entre clases
- Configuracion multiplataforma (Windows, Linux, macOS)
- Filtro nearest neighbor para texturas pixel-perfect
- Sistema de metricas en tiempo real (FPS, V-Sync)
🐛 Problemas Conocidos
- FPS drops significativos con >10,000 pelotas
- Timing dependiente del framerate (solucion en desarrollo)
- Sin interpolacion en el renderizado
Proyecto desarrollado como base para experimentacion con game loops y fisica en tiempo real usando SDL3.