Problemas resueltos: - En modo F3 (letterbox), el overlay se centraba en pantalla física en lugar de en el viewport visible, quedando desplazado - Al salir de F3 a ventana, el overlay seguía roto - Padding inferior no se respetaba correctamente Cambios implementados: 1. render() ahora usa SDL_GetRenderViewport() para obtener área visible 2. Centrado calculado dentro del viewport (con offset de barras negras) 3. toggleFullscreen() restaura tamaño de ventana al salir de F3 4. Padding check movido ANTES de escribir línea (>= en lugar de >) 5. Debug logging añadido para diagnóstico de dimensiones Resultado: ✅ Overlay centrado correctamente en F3 letterbox ✅ Overlay se regenera correctamente al salir de F3 ✅ Padding inferior respetado en columna 0 Pendiente: - Columna 2 (índice 1) todavía no respeta padding inferior - Verificar que F4 (real fullscreen) siga funcionando correctamente 🤖 Generated with 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.