Desarrollo · Sardinia Drive
Cómo construimos el motor gráfico de Sardinia Drive
Cómo una carretera definida a lo largo de una ruta se convierte en una escena en perspectiva con Canvas 2D.
Una carretera en dos coordenadas
En el motor de la alfa, z es la distancia a lo largo de la etapa y x es el desplazamiento lateral. Cada curva tiene un inicio, un final y un cambio de dirección. Si t es el avance de 0 a 1 dentro de la curva, su contribución a la dirección sigue 3t² − 2t³. La pendiente de esa función vale cero en ambos extremos, de modo que la curvatura aumenta y disminuye de forma gradual.
Al muestrear la carretera se obtiene la posición del centro, la dirección y la curvatura. El modelo de conducción consulta la curvatura cuatro unidades por delante y la cámara toma la tangente en la posición del jugador. La misma curva de Lago Cuga determina tanto el dibujo como el empuje lateral que se siente al volante.
De la distancia a los píxeles
El motor mide el desplazamiento lateral del punto muestreado respecto a la tangente de la carretera en la posición del jugador. En la fórmula, baseHeading es la pendiente lateral local, multiplicada por la distancia hacia delante. También resta el 87% del desplazamiento lateral del vehículo, de forma que la cámara lo sigue parcialmente al girar. Luego convierte esos desplazamientos en píxeles multiplicándolos por la distancia focal dividida entre la profundidad.
depth = roadPointZ - playerZ
scale = focalLength / depth
offset = roadCenter - baseCenter - baseHeading * depth
screenX = canvasWidth / 2 + (offset - 0.87 * playerX) * scale
screenY = horizonY + cameraHeight * scale
Tomemos un búfer Canvas de 900 × 600 píxeles durante una carrera. El horizonte está en y = 243, la distancia focal es 396 y la altura de la cámara es de 2,05 unidades. Para una sección de 7,8 unidades de ancho, la proyección da estos resultados.
| Profundidad | Ancho en píxeles | Fila del canvas |
|---|---|---|
| 15 unidades | 206 | 297 |
| 30 unidades | 103 | 270 |
Al duplicar la distancia, tanto el ancho como la separación vertical respecto al horizonte se reducen a la mitad. El aumento de escala en primer plano es una de las señales visuales de velocidad.
Una carretera hecha de cuadriláteros
El motor recorre hasta 225 unidades por delante del jugador en pasos de 3. Proyecta las secciones cercana y lejana de cada franja y une sus cuatro vértices. En la misma pasada dibuja el asfalto, los bordes y las marcas del centro con desplazamientos laterales distintos. Las franjas lejanas se dibujan primero y la más cercana se corta a 1,35 unidades de la cámara, donde dividir entre la profundidad haría crecer demasiado la escala.
La orilla de Lago Cuga funciona igual. El lago alcanza su ancho máximo en el centro y sigue un perfil parabólico hasta llegar a cero a 170 unidades del centro. El motor calcula un ancho para cada extremo de la franja. El borde del carril cerrado en las obras también parte de un desplazamiento lateral y sigue la curva del asfalto.
Cómo se superponen los sprites
Tras dibujar la carretera, el motor reúne los objetos del arcén, el tráfico y el vehículo del jugador en una lista ordenada por z, de más lejos a más cerca. Un autobús cercano puede tapar un olivo dibujado antes. La ordenación usa un punto de anclaje por sprite. Cuando se cruzan siluetas grandes, la superposición es aproximada.
Para el jugador, el motor calcula a qué profundidad queda el eje trasero al 82% de la altura de la pantalla. Añade el eje a la misma lista y aplica al tráfico el mismo desplazamiento en profundidad. Los vehículos del jugador tienen tres poses de 320 × 320 píxeles en un atlas WebP. El giro y el derrape seleccionan la pose y el motor añade rotación y sombra.
Horizonte, encuadre y coste en píxeles
El fondo de Capo Caccia se divide en la línea del agua. El motor alinea las dos partes con el horizonte de la carretera y desplaza los reflejos a distintas velocidades. Al llegar a la meta en una pantalla vertical, la distancia focal baja hasta el 77% del valor de carrera y el encuadre se amplía. El cronómetro y el indicador de progreso son elementos HTML sobre el canvas y permanecen fijos.
El búfer del canvas usa la densidad de píxeles del dispositivo con un límite de 1,5. En un teléfono de 3×, el búfer contiene aproximadamente una cuarta parte de los píxeles que tendría a resolución nativa. El navegador escala el resultado a la zona visible. Con este ajuste se limita la cantidad de píxeles que hay que volver a dibujar.