Este documento describe la integración del motor de física Rapier3D en el cliente de Redblock.
El juego utiliza Rapier3D (@dimforge/rapier3d-compat) como motor de física para:
- ✅ Detección de colisiones realistas
- ✅ Gravedad y dinámica de saltos
- ✅ Sliding suave en paredes
- ✅ Character controller para movimiento del jugador
- ✅ Detección de suelo (grounded state)
Clase principal que envuelve Rapier3D y mantiene compatibilidad con la API anterior.
Características:
- Mundo de física con gravedad configurable (-24 m/s²)
- Character controller con:
- Auto-step para subir escalones (0.5m)
- Snap-to-ground para mantener contacto con el suelo
- Sliding habilitado para movimiento suave en paredes
- Gestión de colisiones estáticas (cubos, plataformas)
- API asíncrona con
waitForInit()para garantizar inicialización
Métodos clave:
// Añadir colisionador
addCollider(box: CollisionBox): void
// Mover jugador con colisiones
slidePlayerAlongWalls(position: Vector3, movement: Vector3): Vector3
// Detectar suelo
checkGroundCollision(position: Vector3, maxDistance: number): number | null
isGrounded(): boolean
// Actualizar simulación
step(deltaTime: number): void// Crear sistema de física
this.collisionSystem = new PhysicsSystem();
await this.collisionSystem.waitForInit();
// Configurar dimensiones del jugador
this.collisionSystem.setPlayerDimensions(0.25, 1.8); // radio, altura
this.collisionSystem.setStepHeight(0.5); // altura máxima de escalón
// En el update loop
this.collisionSystem.step(deltaTime);El sistema de física se usa en el loop de actualización para:
- Movimiento horizontal:
slidePlayerAlongWalls()maneja colisiones y sliding - Movimiento vertical:
pushOutOfColliders()resuelve penetraciones - Detección de suelo:
checkCapsuleCollision()verifica si está en el aire
- Valor: -24 m/s²
- Ubicación:
PhysicsSystemconstructor - Se aplica automáticamente por el mundo de Rapier
- Radio: 0.25m (cápsula)
- Altura: 1.8m
- Forma: Cápsula (mejor para movimiento de personaje)
- Tipo: Kinematic position-based (controlado manualmente)
characterController.enableAutostep(0.5, 0.1, true);
characterController.enableSnapToGround(0.5);
characterController.setSlideEnabled(true);Los bloques del escenario se añaden como:
- Tipo: Static rigid body
- Forma: Cuboid (caja)
- Cálculo: Automático desde bounds de Three.js
En gameBootstrap.ts, los bloques del editor se convierten en colisionadores:
// Esperar inicialización
await app.collisionSystem.waitForInit();
// Crear collider desde bounds
const collider = {
min: new Vector3(...),
max: new Vector3(...),
object: cube
};
app.collisionSystem.addCollider(collider);- Paso de física: Llamado cada frame en
App.update() - Inicialización: Asíncrona (Rapier WASM)
- Colliders estáticos: Sin overhead después de creación
- Character controller: Optimizado para juegos de primera persona
Para visualizar colisionadores:
const helpers = physicsSystem.debugDrawColliders(scene);| Característica | CollisionSystem (Viejo) | PhysicsSystem (Rapier) |
|---|---|---|
| Motor | Custom AABB | Rapier3D |
| Gravedad | Manual | Automática |
| Sliding | MTV-based | Character controller |
| Performance | Buena para pocos objetos | Escalable |
| Realismo | Básico | Alto |
| Detección | Cápsula sampledada | Narrow-phase precisa |
- Verificar que los colisionadores se añadieron después de
waitForInit() - Revisar que las dimensiones del collider coincidan con el mesh visible
- Asegurar que
physicsSystem.step()se llama cada frame - Verificar que
deltaTimesea consistente
- Confirmar que Rapier se inicializó:
await waitForInit() - Verificar que los colliders tienen dimensiones válidas (>0)
- Añadir objetos dinámicos (cajas movibles)
- Sistema de triggers/zonas
- Raycasting para armas con precisión física
- Debug overlay para visualizar fuerzas
- Profiling de performance