> **Versión:** Fase 1 (Motor Base Pseudo-3D)  
> **Stack:** HTML5 Canvas 2D, JavaScript Vanilla (ES5/ES6 híbrido), CSS3  
> **Inspiración:** Out Run, Road Rash, Need for Speed 1, estética New Retro Net / Synthwave  
> **Propósito final:** Un juego arcade de carreras pseudo-3D que funcione como videoclip interactivo para una canción por estrenar.

 ██████╗  ██████╗ ███╗   ███╗███████╗██████╗ ██╗████████╗ █████╗ 
██╔════╝ ██╔═══██╗████╗ ████║██╔════╝██╔══██╗██║╚══██╔══╝██╔══██╗
██║  ███╗██║   ██║██╔████╔██║█████╗  ██████╔╝██║   ██║   ███████║
██║   ██║██║   ██║██║╚██╔╝██║██╔══╝  ██╔══██╗██║   ██║   ██╔══██║
╚██████╔╝╚██████╔╝██║ ╚═╝ ██║███████╗██║  ██║██║   ██║   ██║  ██║
 ╚═════╝  ╚═════╝ ╚═╝     ╚═╝╚══════╝╚═╝  ╚═╝╚═╝   ╚═╝   ╚═╝  ╚═╝
---

## 1. Arquitectura del Código

El proyecto usa una arquitectura modular con 5 archivos separados por responsabilidad. **No hay bundler ni framework.** Todo corre en el navegador abriendo `index.html`.

### Estructura de archivos

```javascript
retro-racer/
├── index.html          # Estructura DOM, carga de scripts
├── css/
│   └── style.css       # Estilos base, HUD, paleta synthwave
└── js/
    ├── engine.js       # Configuración global, constantes, utilidades matemáticas, input
    ├── road.js         # Generador procedural de la pista (segmentos, curvas, colinas)
    ├── renderer.js     # Motor de renderizado pseudo-3D, dibujo de carretera, fondo, jugador
    └── main.js         # Game loop, física arcade, integración
```

### Patrones de código

- **Namespace pattern:** Cada módulo es un objeto global (`Engine`, `Road`, `Renderer`, `Game`). No usa clases ES6 ni módulos ES6. Esto facilita que DeepSeek/Copilot modifique sin romper imports.
- **Métodos con `this` explícito:** Todos los métodos de los objetos namespace se definen como `propiedad: function() { ... }` (no arrow functions), por lo que `this` siempre apunta al objeto contenedor.
- **Sin dependencias externas:** No hay npm, no hay bundler, no hay frameworks. Solo Canvas 2D API nativa.
- **Comentarios en español:** Todo el código está comentado en español para mantener consistencia con el equipo.

---

## 2. Cómo Modificar Cada Parte

### 2.1 engine.js — El "cerebro" de configuración

**Qué contiene:**

- Dimensiones del canvas (`width`, `height`)
- Parámetros de cámara y perspectiva (`cameraHeight`, `cameraDepth`, `fieldOfView`, `drawDistance`)
- Parámetros de la carretera (`segmentLength`, `roadWidth`, `lanes`, `rumbleLength`)
- Estado del jugador (`playerX`, `playerZ`, `speed`, `maxSpeed`, `accel`, etc.)
- Sistema de input de teclado (`keys`, `bindKeys()`, `keyDown()`)
- Utilidades matemáticas (`limit`, `interpolate`, `easeIn`, `easeOut`, `easeInOut`, `percentRemaining`)

**Cómo modificar:**

- Para cambiar la velocidad máxima: editar `maxSpeed: 12000`
- Para cambiar la aceleración: editar `accel: 3000`
- Para cambiar cuántos segmentos se ven a la vez: editar `drawDistance: 300`
- Para cambiar el ancho de la carretera: editar `roadWidth: 2000`
- Para agregar nuevas constantes (ej: `turbo`, `driftFriction`): añadir propiedades al objeto `Engine` y luego usarlas en `main.js` o `renderer.js`

**Regla de oro:** Siempre que agregues una nueva propiedad a `Engine`, inicializala con un valor por defecto. Los otros archivos la leen como `Engine.propiedad`.

### 2.2 road.js — El generador de pista

**Qué contiene:**

- Array `segments`: cada elemento es un trapecio 3D con dos puntos (`p1`, `p2`), curva, elevación y color.
- Paleta de colores de la carretera (`colors.light`, `colors.dark`, `colors.start`, `colors.finish`)
- Funciones para construir tramos: `addStraight`, `addCurve`, `addSCurve`, `addHill`, `addRoad`
- Función `generate()` que arma el layout completo de la pista
- `findSegment(z)` para saber en qué segmento está el jugador

**Cómo modificar:**

- Para cambiar la forma de la pista: editar únicamente la función `generate()`.
- **Sintaxis de `addRoad(enter, hold, leave, curve, height)`:**
- `enter`: segmentos de transición de entrada (suavizado)
- `hold`: segmentos de curva/elevación constante
- `leave`: segmentos de transición de salida (suavizado)
- `curve`: curvatura lateral. `0` = recta, `2` = curva suave, `4` = curva cerrada, negativo = izquierda
- `height`: elevación total del tramo en unidades de mundo. `2000` = subida, `-2000` = bajada, `0` = plano

**Problemas comunes a evitar:**

- Curvas o colinas muy bruscas (valores altos de `curve` o `height` con pocos segmentos de transición) generan artefactos visuales donde la carretera parece "vertical" o da saltos.
- Solución: mantener `enter` y `leave` ≥ 50 segmentos para curvas pronunciadas. Usar `curve` entre -4 y 4, `height` entre -3000 y 3000.

### 2.3 renderer.js — El pintor

**Qué contiene:**

- `project(p, cameraX, cameraY, cameraZ, ...)` — proyección matemática 3D→2D
- `render(...)` — loop de dibujo principal: fondo → carretera → jugador
- `drawSky()` — gradiente synthwave, sol, estrellas, grid horizontal
- `drawSegment()` — dibuja una franja de carretera (césped, bordes, asfalto, líneas)
- `drawPlayer()` — placeholder geométrico del auto (rectángulos con glow)
- `drawPolygon()` — utilidad para dibujar polígonos rellenos

**Cómo modificar:**

- Para cambiar el cielo: editar `drawSky()` (gradientes, posición del sol, cantidad de estrellas)
- Para cambiar cómo se ve la carretera: editar `drawSegment()` y los colores en `engine.js`
- Para cambiar el auto del jugador: editar `drawPlayer()`. Actualmente es un rectángulo magenta; en Fase 3 se reemplazará por sprites.
- **Importante:** `drawSegment` usa `Engine.width` y `Engine.height` para referirse al tamaño del canvas. No usar variables `width` o `height` sueltas.

### 2.4 main.js — El director de orquesta

**Qué contiene:**

- `Game.init()` — inicializa todo y arranca el loop
- `Game.loop(time)` — `requestAnimationFrame`, delta time, FPS counter
- `Game.updatePhysics()` — aceleración, frenado, giro, fricción, colisión con bordes, loop de pista
- `Game.updateHUD()` — actualiza velocímetro y efectos visuales del HUD

**Cómo modificar:**

- Para cambiar el comportamiento del auto: editar `updatePhysics()`.
- Para cambiar las teclas: editar las condiciones `Engine.keyDown('ArrowUp')`, etc. Los códigos de tecla usan `KeyboardEvent.code` (ej: `'KeyW'`, `'ShiftLeft'`, `'Space'`).
- Para agregar nuevos estados de juego (menú, pausa, game over): agregar una máquina de estados en `Game`.

### 2.5 style.css — La piel

**Qué contiene:**

- Layout full-screen del canvas
- Paleta de colores synthwave aplicada al body y contenedor
- Estilos del HUD (velocímetro neón, info de debug)

**Cómo modificar:**

- Cambiar colores del HUD: editar `#speedometer` (magenta `#ff00ff`) y `#debug-info` (cian `#00ffff`)
- Cambiar fuentes: reemplazar `'Courier New'` por otra fuente monospace o pixelada
- El fondo del juego se dibuja en Canvas (`drawSky`), no en CSS. CSS solo da el color base del body.

---

## 3. Sistema de Proyección Pseudo-3D (Cómo funciona por dentro)

Este NO es un motor 3D real (no usa WebGL ni Three.js). Es una simulación 2D basada en la técnica clásica de *Mode 7* / *Outrun*:

1. **El mundo es una lista de segmentos** apilados en el eje Z (profundidad).
2. **Cada segmento es un trapecio** definido por dos puntos: `p1` (más lejano) y `p2` (más cercano).
3. **La cámara está en una posición fija** detrás del jugador, a una altura `cameraHeight`.
4. **Para cada frame:** se recorren los segmentos desde el más cercano hasta el `drawDistance`.
5. **Cada punto 3D se proyecta a 2D** con la fórmula:

```javascript
   scale = cameraDepth / (worldZ - cameraZ)
   screenX = (canvasWidth / 2) + (scale * worldX * canvasWidth / 2)
   screenY = (canvasHeight / 2) - (scale * worldY * canvasHeight / 2)
   screenW = scale * roadWidth * canvasWidth / 2
```

6. **Las curvas se simulan** acumulando un offset lateral (`dx`) por cada segmento. Esto desplaza la carretera horizontalmente creando la ilusión de giro.
7. **Las colinas se simulan** con la coordenada Y del mundo. Al subir o bajar, `screenY` cambia y la carretera parece ondularse.
8. **El orden de dibujo es de atrás hacia adelante** (painter's algorithm), así los segmentos cercanos tapan a los lejanos.

---

## 4. Resultado Visual Buscado (Fase Final)

### Estética: New Retro Net / Synthwave

| Elemento | Descripción |
| --- | --- |
| **Paleta** | Magenta neón (`#ff00ff`), cian eléctrico (`#00ffff`), fondo azul-noche profundo (`#0a0a1a`), púrpuras intermedios. |
| **Cielo** | Gradiente vertical de oscuro a púrpura, sol synthwave estilo atardecer (degradado magenta→naranja), estrellas parpadeantes, grid horizontal que simula perspectiva. |
| **Carretera** | Asfalto oscuro con bordes magenta/cian alternados, líneas de carril cian intermitentes, césped oscuro a los costados. |
| **Vehículo** | Sprite de moto/auto estilo pixel art o ilustración vectorial retro, con luces traseras rojas y estela de luz a alta velocidad. |
| **Ambiente** | Sprites de palmeras, postes de luz neón, edificios distantes, montañas en el horizonte. Todo escalado por distancia. |
| **HUD** | Velocímetro digital estilo VFD (vacuum fluorescent display), barras de estado, minimapa opcional. Todo con glow/bloom sutil. |
| **Partículas** | Estelas de luz al acelerar, chispas al derrapar, humo al frenar. |
| **Atmósfera** | Todo en tiempo nocturno. Velocidad = sensación de movimiento fluido. |

### Gameplay objetivo

- Carrera infinita (o de duración = duración de la canción)
- Acelerar, frenar, girar, derrapar
- Posibilidad futura: golpear rivales tipo Road Rash
- Sincronización de eventos de pista (curvas, saltos, cambios de escenario) con momentos clave de la canción

---

## 5. Roadmap de Desarrollo Sugerido

### ✅ Fase 1 — ESQUELETO MATEMÁTICO Y LOOP GRÁFICO *(COMPLETADA)*

- Motor pseudo-3D funcional
- Proyección, segmentos, curvas, colinas
- Fondo synthwave básico
- Auto placeholder geométrico
- Controles básicos (↑↓←→ / WASD)

### 🔧 Fase 2 — FÍSICA ARCADE PULIDA *(SIGUIENTE)*

- Velocidad lateral con inercia (`speedX`)
- Derrape con `Shift`/`Space`
- Turbo con doble tap de acelerar
- Fricción diferenciada (tierra vs. asfalto vs. fuera de pista)
- Rebote en barreras
- Inclinación visual del auto (`lean`)
- Partículas placeholder (humo, chispas)
- Vibración de cámara en bordes

### 🎨 Fase 3 — SISTEMA DE SPRITES

- Cargar imágenes PNG con transparencia
- Sistema de `z-indexing` visual (sprites lejanos detrás, cercanos delante)
- Escalado de sprites según distancia (`screen.scale`)
- Sprites estáticos: palmeras, postes, edificios
- Sprite del jugador reemplaza placeholder geométrico
- Sprites de rivales (motociclistas)

### 🎵 Fase 4 — ATMÓSFERA "NEW RETRO NET" Y AUDIO

- Integrar canción (Web Audio API o `<audio>`)
- Sincronizar eventos de pista con la música (beats, drops)
- HUD definitivo (velocímetro VFD, barras, minimapa)
- Fondo con parallax mejorado
- Partículas finales (estelas, chispas, humo)
- Post-procesado sutil (scanlines, vignette, bloom simulado con `shadowBlur`)
- Optimización de rendimiento (reducir `drawDistance` en móviles, object pooling)

### 🥊 Fase 5 — COMBATE Y RIVALES *(OPCIONAL / POST-RELEASE)*

- IA de rivales con comportamiento de carrera
- Detección de proximidad lateral
- Animaciones de golpe/patada/caída
- Estados: montado, cayendo, recuperándose
- Sistema de puntuación / tiempo / posición

### 🚀 Fase 6 — DEPLOY Y POLISH

- Pantallas: título, instrucciones, game over, créditos
- Responsive (adaptar a móviles con controles táctiles)
- PWA (instalable, offline)
- Hosting y compartir