¿Cómo se determinaría la position de un participante en un juego de carreras?

Ahora, para que conste, actualmente no estoy implementando ningún juego de carreras, pero este problema acaba de aparecer en mi mente y ahora tengo curiosidad.

Entonces, ¿cómo se puede averiguar qué participante de una carrera es actualmente el primero? No puede ser algo trivial como simplemente orderar por distancia a la línea de llegada porque eso sería altamente inexacto en la mayoría de los cursos. He pensado en hacer algo así como separar la ruta en segmentos rectos, cada uno de los cuales tiene un vector de dirección. El juego luego verificaría si alguien supera a alguien más al proyectar sus posiciones en ese vector y verificar cuál está adelante. Si la position ha cambiado, el juego los incrementará / disminuirá apropiadamente. Pero eso parece demasiado complicado.

¿Alguien sabe de algún método establecido o tiene alguna experiencia en la implementación de algunos?

Shawn Hargreaves describe cómo MotoGP utilizó un sistema especial de position de pista . Ignorando la position vertical y, las coorderadas cartesianas x / z se traducen a un sistema relativo a la pista. Esto tiene muchos beneficios para los cálculos que involucran las posiciones relativas de los participantes en un juego de carreras (por ejemplo, para la IA):

Una simplificación común es queuepsar 3D en 2D. A pesar de que el renderizado y la física pueden ser realmente 3D, la lógica de toma de decisiones no necesita tratar los tres ejes por igual. Las pistas de MotoGP tienen pocas pendientes, por lo que nuestra IA pudo ignorar el componente y.

Luego, cambiamos de coorderadas cartesianas x / z a un sistema relativo a pistas. Las posiciones fueron representadas por un par de valores:

int distance = qué tan lejos está alnetworkingedor de la pista, almacenado en 16.16 formatting de punto fijo

  • 0 = línea de partida
  • 0x8000 = a la mitad
  • 0x10000 = vuelta al inicio
  • 0x1C000 = tres cuartos del path a través de la segunda vuelta

cruz de flotador = qué tan de lado a través de la pista 0 = en la línea central

  • -1 = borde izquierdo de la superficie de carrera
  • 1 = borde derecho de la superficie de carrera

Para convertir esto y las coorderadas cartesianas usadas por nuestro código de física y renderización, almacenamos una list de segmentos que definen la forma de la superficie de carrera: struct TrackSegment {Vector CenterPoint; flotante DistanceToLeftEdge; flotante DistanceToRightEdge; }

Creamos varios cientos de estas estructuras, espaciadas uniformemente alnetworkingedor de la pista, al teselar las curvas de Bezier de las cuales se crearon originalmente las pistas. Esto nos dio suficiente información para escribir las funciones necesarias de conversión de coorderadas.

Con las coorderadas relativas a la pista, muchos cálculos útiles se vuelven trivialmente simples:

if (abs(cross) > 1) // You are off the track and should steer back toward the center line if (this.distance > other.distance) // You are ahead of the other player (even though you may be // physically behind in 3D space if you have lapped them) short difference = (short)(this.distance - other.distance); if (abs(difference) < threshold) // These two bikes are physically close together, // so we should run obstacle avoidance checks 

Debido al formatting de datos de punto fijo, convertir el contador de distancia de 32 a 16 bits fue una manera fácil de descartar el número de vueltas, por lo que pudimos elegir qué cálculos importaban si dos bicicletas estaban en vueltas diferentes, en lugar de querer saber si estaban cerca en el espacio físico. Gracias a la magia del cumplido de dos, tratar la diferencia como signo de 16 bits da la distancia más corta, independientemente de la bicicleta que esté delante (recuerde que en un sistema aritmético modular como una pista de bucle existen dos distancias posibles, como puede medir en cualquier dirección alnetworkingedor de la pista). Esto funciona incluso cuando las dos bicicletas están en lados opuestos de la línea de partida, una situación que requeriría lógica de casos especiales propensa a errores en la mayoría de los demás sistemas de coorderadas.

Aplanar y enderezar este área de juego virtual hace que sea fácil razonar sobre cosas como "¿estoy en la línea de carreras?" o "Estoy subiendo rápidamente detrás de esta otra bicicleta: ¿tengo más espacio para pasarlos a la izquierda o a la derecha?" lo que hubiera sido difícil de implementar en un espacio mundial en 3D completo. Una vez que decidimos pasar a la izquierda, convertiríamos la coorderada relativa de seguimiento resultante en el espacio mundial, momento en el que se tiene en count la curvatura de la pista, que muestra cómo debemos dirigir para lograr nuestra meta elegida.

Supongo que usaría el hecho de que la carretera generalmente se construye utilizando splines, por lo tanto, cada borde de la carretera tiene una position spline correspondiente, y con eso se puede determinar (aproximadamente, o grano fino si subdivide más) lo que el actual la position spline de cada auto es, y por lo tanto, quién está a la cabeza. Así que más o less la forma en que sugieres, simplemente usando la spline.

Creo que has respondido más o less a tu propia pregunta. Divida la ruta en segmentos, registre en qué segmento se encuentra cada automobile y proyecte los automobilees en una línea a la mitad del segmento apropiado (matemáticamente es un producto de puntos simple, por lo que no es complicado en absoluto). Es muy simple darle a cada automobile una "distancia" que puede clasificar para su position.

Los segmentos le brindan algún beneficio adicional: puede asegurarse de que los autos no corten esquinas (o toma de atajos en general), retroceden u otras trampas.