Mejoras de rendimiento y usabilidad del Help Overlay: 1. Anchura dinámica basada en contenido: - Ya no es siempre cuadrado (box_size_) - Calcula ancho real según texto más largo por columna - Mantiene mínimo del 90% dimensión menor como antes - Nueva función calculateTextDimensions() 2. Render-to-texture caching para optimización: - Renderiza overlay completo a textura una sola vez - Detecta cambios de color con umbral (threshold 5/255) - Soporta temas dinámicos con LERP sin rebuild constante - Regenera solo cuando colores cambian o ventana redimensiona 3. Impacto en performance: - Antes: 1200 FPS → 200 FPS con overlay activo - Después: 1200 FPS → 1000-1200 FPS (casi sin impacto) - Temas estáticos: 1 render total (~∞x más rápido) - Temas dinámicos: regenera cada ~20-30 frames (~25x más rápido) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
ViBe3 Physics - Simulador de Sprites con Fisica
ViBe3 Physics es una demo experimental de vibe-coding que implementa nuevas fisicas expandiendo sobre el sistema de delta time. Utiliza SDL3 para mostrar sprites (pelotas) rebotando con fisica avanzada independiente del framerate.
El nombre refleja su proposito: ViBe (vibe-coding experimental) + Physics (nuevas fisicas experimentales). La demo sirve como sandbox para probar bucles de juego con timing independiente y renderizado optimizado.
🎯 Caracteristicas Actuales
- Simulacion de fisica: Gravedad, rebotes y colisiones con perdida de energia
- Multiples escenarios: 8 configuraciones predefinidas (1 a 100,000 pelotas)
- Sistema de temas visuales: 6 temas de colores con fondos degradados y paletas tematicas
- Transiciones LERP: Cambios de tema suaves y fluidos (0.5s) sin reiniciar escenario
- Hot-swap de sprites: Cambio de textura dinamico (ball.png ↔ ball_small.png) con tecla N
- Sistema de zoom dinamico: F1/F2 para ajustar el zoom de ventana (1x-10x)
- Modos fullscreen: F3 para fullscreen normal (mantiene aspecto), F4 para real fullscreen con resolucion nativa
- Escalado configurable: F5 alterna entre INTEGER (mantiene aspecto) y STRETCH (pantalla completa) en modo F3
- Gravedad multidireccional: Gravedad hacia abajo, arriba, izquierda o derecha
- 8 Figuras 3D: Esfera, Wave Grid, Helix, Torus, Cubo, Cilindro, Icosaedro, Atom
- Interactividad: Controles de teclado para modificar el comportamiento
- Renderizado batch optimizado: Sistema de batch rendering con SDL_RenderGeometry para 50K+ sprites
- Colores tematicos: Paletas de 8-24 colores por tema aplicadas proceduralmente
- Monitor de rendimiento: Contador FPS en tiempo real
- Control V-Sync: Activacion/desactivacion dinamica del V-Sync
🎮 Controles
Controles de Sistema
| Tecla | Accion |
|---|---|
H |
Alternar debug display (FPS, V-Sync, valores fisica) |
V |
Alternar V-Sync ON/OFF |
ESC |
Salir del programa |
Controles de Ventana
| Tecla | Accion |
|---|---|
F1 |
Zoom out (reducir zoom ventana) |
F2 |
Zoom in (aumentar zoom ventana) |
F3 |
Toggle fullscreen normal (mantiene aspecto) |
F4 |
Toggle real fullscreen (resolucion nativa) |
F5 |
Toggle escalado INTEGER/STRETCH (solo en modo F3) |
Controles de Temas
| Tecla | Accion |
|---|---|
KP_1 |
Tema ATARDECER (colores calidos) |
KP_2 |
Tema OCEANO (azules y cianes) |
KP_3 |
Tema NEON (colores vibrantes) |
KP_4 |
Tema BOSQUE (verdes naturales) |
KP_5 |
Tema RGB (fondo blanco, colores matematicos) |
KP_6 |
Tema MONOCHROME (fondo negro, todas las pelotas blancas) |
B |
Ciclar entre todos los temas |
N |
Cambiar sprite (ball.png ↔ ball_small.png) |
Controles de Simulacion
| Tecla | Accion |
|---|---|
1-8 |
Cambiar numero de pelotas (1, 10, 100, 500, 1K, 10K, 50K, 100K) |
ESPACIO |
Impulsar todas las pelotas hacia arriba |
↑ |
Gravedad hacia ARRIBA (sale de figura con gravedad) |
↓ |
Gravedad hacia ABAJO (sale de figura con gravedad) |
← |
Gravedad hacia IZQUIERDA (sale de figura con gravedad) |
→ |
Gravedad hacia DERECHA (sale de figura con gravedad) |
G |
Alternar gravedad ON/OFF / Sale de figura SIN gravedad |
Controles de Figuras 3D
| Tecla | Accion |
|---|---|
F |
Toggle entre modo FISICA ↔ última FIGURA 3D |
Q |
Activar figura SPHERE (Esfera Fibonacci) |
W |
Activar figura WAVE GRID (Malla ondeante) |
E |
Activar figura HELIX (Espiral helicoidal) |
R |
Activar figura TORUS (Toroide/donut) |
T |
Activar figura CUBE (Cubo rotante triple XYZ) |
Y |
Activar figura CYLINDER (Cilindro) |
U |
Activar figura ICOSAHEDRON (Icosaedro D20) |
I |
Activar figura ATOM (Núcleo + órbitas) |
KP_+ |
Aumentar escala de figura (+10%) |
KP_- |
Reducir escala de figura (-10%) |
KP_* |
Reset escala de figura a 100% |
KP_/ |
Toggle zoom por profundidad Z (perspectiva ON/OFF) |
📊 Informacion en Pantalla
- Centro: Numero de pelotas activas en blanco (temporal)
- Centro: Nombre del tema activo en color tematico (temporal, debajo del contador)
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
- Lineas 3-5: Valores fisica primera pelota (GRAV, VY, SURFACE, LOSS) en magenta
- Linea 6: Dirección de gravedad actual (GRAVITY UP/DOWN/LEFT/RIGHT) en amarillo
- Linea 7: Tema activo (THEME SUNSET/OCEAN/NEON/FOREST/RGB) en amarillo claro
- Linea 8: Modo de simulación (MODE PHYSICS/SPHERE/CUBE/etc.) en verde claro
🎨 Sistema de Temas de Colores
ViBe3 Physics incluye 6 temas visuales que transforman completamente la apariencia del simulador:
Temas Disponibles
| Tecla | Tema | Descripcion | Fondo | Paleta de Pelotas |
|---|---|---|---|---|
KP_1 |
ATARDECER | Colores calidos de puesta de sol | Degradado naranja-rojo | Tonos naranjas, rojos y amarillos |
KP_2 |
OCEANO | Ambiente marino refrescante | Degradado azul-cian | Azules, cianes y verdes agua |
KP_3 |
NEON | Colores vibrantes futuristas | Degradado magenta-cian | Magentas, cianes y rosas brillantes |
KP_4 |
BOSQUE | Naturaleza verde relajante | Degradado verde oscuro-claro | Verdes naturales y tierra |
KP_5 |
RGB | Colores matematicos puros | Fondo blanco solido | RGB puros y subdivisiones matematicas |
KP_6 |
MONOCHROME | Estetica minimalista monocromatica | Degradado negro | Todas las pelotas blancas puras |
Controles de Temas
- Seleccion directa: Usa
KP_1aKP_6para cambiar al tema deseado - Ciclado secuencial: Presiona
Bpara avanzar al siguiente tema en orden - Transiciones suaves: Cambios de tema con interpolación LERP (0.5 segundos)
- Sin reinicio: Mantiene física y posiciones, solo cambia colores
- Indicador visual: Nombre del tema aparece temporalmente en centro de pantalla
Sistema de Sprites Dinámico
- Tecla N: Cambia entre ball.png (10x10) y ball_small.png (6x6)
- Hot-swap: Sin reiniciar física, actualiza textura y hitbox al instante
- Ajuste automático: Posiciones corregidas según gravedad y superficie
- Tamaño dinámico:
current_ball_size_obtenido desdetexture->getWidth() - Texto informativo: Muestra "SPRITE: NORMAL" o "SPRITE: SMALL"
Detalles Tecnicos
- Fondos degradados: Implementados con
SDL_RenderGeometryusando vertices con colores interpolados - Paletas tematicas: 8-24 colores por tema (RGB tiene 24, resto 8)
- Interpolación LERP: Transiciones RGB suaves frame-a-frame durante 0.5s
- Sin regeneración: Cambio de tema no llama
initBalls(), solo actualiza colores - Rendimiento optimizado: LERP tiene overhead mínimo (<1ms con 10K pelotas)
- Compatibilidad completa: Funciona con todos los escenarios (1 a 100,000 pelotas)
🎯 Sistema de Figuras 3D - Efectos Demoscene
ViBe3 Physics incluye un sistema polimórfico de figuras 3D que convierte las pelotas en formas geométricas rotantes proyectadas en 2D.
Figuras Implementadas (8/8 Completas)
🌐 SPHERE (Tecla Q)
- Algoritmo: Fibonacci Sphere - distribución uniforme de puntos
- Rotación: Dual (ejes X e Y)
- Efecto: Esfera rotante clásica estilo demoscene
🌊 WAVE GRID (Tecla W)
- Algoritmo: Grid NxN con ondas sinusoidales en Z
- Animación: Olas propagándose en tiempo real
- Rotación: XY combinada
- Efecto: Océano ondulante
🧬 HELIX (Tecla E)
- Algoritmo: Espiral helicoidal paramétrica
- Animación: Rotación suave en eje Y
- Altura: 75% de pantalla (ajustable)
- Efecto: DNA/hélice rotante
🍩 TORUS (Tecla R)
- Algoritmo: Toroide paramétrico (radio mayor + radio menor)
- Rotación: Triple eje con velocidades diferentes
- Efecto: Donut flotante estilo demoscene
🎲 CUBE (Tecla T)
- Distribución inteligente:
- 1-8: Solo vértices (8 puntos)
- 9-26: Vértices + caras + aristas (26 puntos)
- 27+: Grid volumétrico 3D uniforme
- Rotación: Triple (X, Y, Z simultáneos)
- Efecto: Cubo Rubik rotante
🏛️ CYLINDER (Tecla Y)
- Algoritmo: Cilindro con tapas circulares
- Rotación: Eje Y (spin horizontal)
- Efecto: Columna griega rotante
⚛️ ICOSAHEDRON (Tecla U)
- Algoritmo: Poliedro regular de 20 caras
- Geometría: 12 vértices, proporción áurea
- Rotación: Triple eje caótico
- Efecto: Dado D20 flotante
⚛️ ATOM (Tecla I)
- Estructura: Núcleo central + 3 órbitas elípticas
- Animación: Electrones en movimiento orbital
- Rotación: Órbitas perpendiculares entre sí
- Efecto: Átomo de Bohr animado
Características Técnicas
- Física de atracción: Sistema spring-damper (Hooke's Law) para transición suave
- Profundidad Z simulada: Color modulado según distancia (oscuro=fondo, brillante=frente)
- Zoom por profundidad: Perspectiva 3D con escala variable (50%-150% según Z)
- Z-sorting: Painter's Algorithm para oclusión correcta
- Escala dinámica: Control manual con Numpad +/- (30% - 300%)
- Protección de clipping: Escala limitada automáticamente según resolución
- Sin sprites adicionales: Usa
SDL_SetTextureColorMody vértices escalados para efectos 3D
Parámetros Físicos (defines.h)
// Física compartida entre todas las figuras
ROTOBALL_SPRING_K = 300.0f; // Rigidez del resorte (N/m)
ROTOBALL_DAMPING_BASE = 35.0f; // Amortiguación crítica
ROTOBALL_DAMPING_NEAR = 80.0f; // Absorción cerca del punto
// Esfera
ROTOBALL_RADIUS_FACTOR = 0.333f; // 33% de altura de pantalla
ROTOBALL_ROTATION_SPEED_Y = 1.5f; // rad/s (eje Y)
ROTOBALL_ROTATION_SPEED_X = 0.8f; // rad/s (eje X)
// Cubo
CUBE_SIZE_FACTOR = 0.25f; // 25% de altura de pantalla
CUBE_ROTATION_SPEED_X = 0.5f; // rad/s
CUBE_ROTATION_SPEED_Y = 0.7f; // rad/s
CUBE_ROTATION_SPEED_Z = 0.3f; // rad/s
// Control manual de escala
SHAPE_SCALE_MIN = 0.3f; // Mínimo 30%
SHAPE_SCALE_MAX = 3.0f; // Máximo 300%
SHAPE_SCALE_STEP = 0.1f; // Incremento 10%
Cómo Funciona
- Generación: Algoritmo específico distribuye puntos en forma 3D
- Rotación: Matrices de rotación 3D aplicadas en tiempo real
- Escala: Factor manual multiplicado a coordenadas y física
- Proyección: Coordenadas 3D → 2D (ortográfica)
- Z-sorting: Ordenar pelotas por profundidad (fondo primero)
- Profundidad: Componente Z controla brillo del color
- Renderizado: Batch rendering con color modulado
Uso
- Activación: Presiona Q/W/E/R/T/Y/U/I para figura específica, o F para toggle
- Escala: Usa Numpad +/- para ajustar tamaño, * para reset
- Perspectiva: Numpad / para activar/desactivar zoom por profundidad (ON por defecto)
- Salir: G (sin gravedad), cursores (con gravedad), F (toggle), o 1-8 (cambiar escenario)
- Compatible: Funciona con 1-100,000 pelotas
- Temas: Mantiene paleta de colores activa
🏗️ Estructura del Proyecto
vibe3_physics/
├── source/
│ ├── main.cpp # Bucle principal y logica del juego
│ ├── engine.h/cpp # Motor principal con loop y rendering
│ ├── ball.h/cpp # Clase Ball - fisica de pelotas
│ ├── defines.h # Constantes y configuracion
│ ├── shapes/ # Sistema polimorfico de figuras 3D
│ │ ├── shape.h # Interfaz abstracta Shape
│ │ ├── sphere_shape.h/cpp # Fibonacci Sphere
│ │ └── cube_shape.h/cpp # Cubo rotante triple
│ └── 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
├── data/
│ ├── ball.png # Textura normal de la pelota (10x10 pixeles)
│ └── ball_small.png # Textura pequeña de la pelota (6x6 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
./vibe3_physics # Linux/macOS
./vibe3_physics.exe # Windows
📊 Detalles Tecnicos
Configuracion Actual
- Resolucion: 320x240 pixeles (escalado x3 = 960x720 por defecto)
- Sistema de timing: Delta time independiente del framerate
- Fisica: Gravedad constante (0.2 px/frame² → 720 px/s²), rebotes con perdida de energia variable (0.30-0.95)
- Tamaño de pelota: Dinámico (10x10 o 6x6 según sprite activo)
- V-Sync: Activado por defecto, controlable dinamicamente
- Temas: 6 temas con transiciones LERP de 0.5s
- Figuras 3D: 8 figuras completas con física de atracción
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
}
🚀 Sistema de Batch Rendering
Problema Original
El renderizado individual de sprites era el principal cuello de botella:
- 50,000 bolas: 50,000 llamadas
SDL_RenderTexture()por frame - Resultado: ~10 FPS (inutilizable)
Solución Implementada: SDL_RenderGeometry
Batch rendering que agrupa todos los sprites en una sola llamada:
// Recopilar datos de todas las bolas
for (auto &ball : balls) {
SDL_FRect pos = ball->getPosition();
Color color = ball->getColor();
addSpriteToBatch(pos.x, pos.y, pos.w, pos.h, color.r, color.g, color.b);
}
// Renderizar TODAS las bolas en una sola llamada
SDL_RenderGeometry(renderer, texture->getSDLTexture(),
batch_vertices.data(), batch_vertices.size(),
batch_indices.data(), batch_indices.size());
Arquitectura del Batch
- Vértices: 4 vértices por sprite (quad) con posición, UV y color
- Índices: 6 índices por sprite (2 triángulos)
- Acumulación: Todos los sprites se acumulan en vectores globales
- Renderizado: Una sola llamada
SDL_RenderGeometrypor frame
Rendimiento Conseguido
- 50,000 bolas: >75 FPS constante (mejora de 750%)
- 100,000 bolas: Fluido y jugable
- Escalabilidad: Preparado para renderizado masivo de sprites
🎨 Sistema de Transiciones LERP
Problema Original
El cambio de temas reiniciaba completamente la simulación:
- Llamaba a
initBalls()regenerando todas las pelotas - Perdía posiciones, velocidades y estado físico
- Cambio brusco e instantáneo
- Disruptivo para la experiencia visual
Solución Implementada: Interpolación Lineal
Transiciones suaves de colores sin afectar la física:
// Variables de transición
bool transitioning_ = false;
float transition_progress_ = 0.0f; // 0.0 a 1.0
float transition_duration_ = 0.5f; // 0.5 segundos
// Función LERP
float lerp(float a, float b, float t) {
return a + (b - a) * t;
}
// Interpolación de colores
Color getInterpolatedColor(size_t ball_index) {
Color current = balls_[ball_index]->getColor();
Color target = target_theme.ball_colors[ball_index % count];
return {
lerp(current.r, target.r, transition_progress_),
lerp(current.g, target.g, transition_progress_),
lerp(current.b, target.b, transition_progress_)
};
}
// En update()
if (transitioning_) {
transition_progress_ += delta_time / transition_duration_;
if (transition_progress_ >= 1.0f) {
// Finalizar transición, actualizar colores permanentes
for (size_t i = 0; i < balls_.size(); i++) {
balls_[i]->setColor(target_colors[i]);
}
transitioning_ = false;
}
}
Características del Sistema
- Interpolación frame-a-frame: Colores RGB calculados en cada frame
- Fondo degradado: También interpola colores de vértices del fondo
- Independiente del framerate: Usa
delta_timepara duración precisa - Sin impacto físico: Mantiene posiciones, velocidades y gravedad
- Overhead mínimo: <1ms adicional con 10,000 pelotas
🔄 Sistema de Hot-Swap de Sprites
Concepto
Cambio dinámico de texturas sin reiniciar la simulación física.
Desafío Técnico: Ajuste de Posiciones
Cuando las pelotas están en reposo en superficies, cambiar el tamaño del hitbox causa problemas:
Caso 1: Grande → Pequeño (10px → 6px)
- Pelota en suelo:
pos.y = screen_height - 10 - Cambia a 6px:
pos.y = screen_height - 6 - Problema: Queda flotando 4 píxeles arriba → Cae de nuevo ❌
Caso 2: Pequeño → Grande (6px → 10px)
- Pelota en suelo:
pos.y = screen_height - 6 - Cambia a 10px: hitbox se entierra 4 píxeles
- Problema: Detección de colisión → Rebote violento hacia arriba ❌
Solución: Ajuste Inteligente de Posiciones
void updateBallSizes(int old_size, int new_size) {
float delta_size = new_size - old_size;
for (auto& ball : balls_) {
if (ball->isOnSurface()) {
// Solo ajustar pelotas en superficie
SDL_FRect pos = ball->getPosition();
switch (ball->getGravityDirection()) {
case DOWN: pos.y += delta_size; break; // Bajar si crece
case UP: pos.y -= delta_size; break; // Subir si crece
case LEFT: pos.x -= delta_size; break;
case RIGHT: pos.x += delta_size; break;
}
ball->updateSize(new_size);
ball->setPosition(pos.x, pos.y);
} else {
// Pelotas en vuelo: solo actualizar tamaño
ball->updateSize(new_size);
}
}
}
Texturas Disponibles
- ball.png: 10x10 píxeles (normal)
- ball_small.png: 6x6 píxeles (pequeño)
Características
- Tamaño dinámico:
current_ball_size_obtenido detexture->getWidth() - Ajuste según gravedad: Posición corregida según dirección gravitacional
- Hot-swap completo: Cambia textura, hitbox y clip del sprite
- Sin reinicio físico: Mantiene velocidades y trayectorias
- Texto informativo: Muestra "SPRITE: NORMAL" o "SPRITE: SMALL"
🛠️ 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
Ninguno conocido. El sistema esta completamente funcional con delta time implementado.
Proyecto desarrollado como base para experimentacion con game loops y fisica en tiempo real usando SDL3.