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


9

Ahora, para que conste, actualmente no estoy implementando ningún juego de carreras, pero este problema se me ocurrió y ahora tengo curiosidad.

Entonces, ¿cómo podría uno averiguar qué participante de una carrera es actualmente el primero? No puede ser algo trivial como simplemente ordenar por distancia a la línea de meta porque eso sería muy inexacto en la mayoría de los recorridos. He pensado en hacer algo como separar la ruta en segmentos rectos, cada uno de los cuales tiene un vector de dirección. Luego, el juego verificará cuándo alguien supera a alguien más al proyectar sus posiciones en ese vector y verificar cuál está por delante. Si la posición ha cambiado, el juego los incrementaría / disminuiría apropiadamente. Pero eso parece un poco demasiado complicado.

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

Respuestas:


12

Shawn Hargreaves describe cómo MotoGP utilizó un sistema especial de posición relativa a la pista . Ignorando la posición vertical y, las coordenadas cartesianas x / z se traducen a un sistema relativo a la pista. Esto tuvo muchos beneficios para los cálculos relacionados con las posiciones relativas de los participantes en un juego de carreras (por ejemplo, para la IA):

Una simplificación común es colapsar 3D en 2D. Aunque 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 colinas, por lo que nuestra IA pudo ignorar el componente y.

A continuación, cambiamos de coordenadas cartesianas x / z a un sistema relativo a la pista. Las posiciones fueron representadas por un par de valores:

distancia int = qué tan lejos alrededor de la pista, almacenada en formato de punto fijo 16.16

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

cruz flotante = qué tan lejos 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 entre esto y las coordenadas cartesianas utilizadas por nuestro código de representación y física, almacenamos una lista 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 alrededor de la pista, al teselar las curvas de Bezier a partir de las cuales se crearon originalmente las pistas. Esto nos dio suficiente información para escribir las funciones de conversión de coordenadas necesarias.

Con las coordenadas 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 formato de datos de punto fijo, convertir el contador de distancia de 32 a 16 bits era una manera fácil de descartar el número de vuelta, para que pudiéramos elegir qué cálculos importarían si dos bicicletas estuvieran 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 16 bits con signo proporciona la distancia más corta, independientemente de la bicicleta que esté al frente (recuerde que en un sistema aritmético de módulo, como una pista de carreras en bucle, hay dos distancias posibles, como puede medir en cualquier dirección alrededor 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 una lógica de caso especial propensa a errores en la mayoría de los otros sistemas de coordenadas.

Al aplanar y enderezar esta área de juego virtual, fue fácil razonar sobre cosas como "¿estoy en la línea de carreras?" o "Estoy subiendo rápido detrás de esta otra bicicleta: ¿tengo más espacio para pasarlos a la izquierda o la derecha?" que habría sido difícil de implementar en un espacio mundial en 3D completo. Una vez que decidimos pasar por la izquierda, convertiríamos la coordenada relativa a la pista resultante nuevamente en el espacio mundial, en ese punto la curvatura de la pista se tiene en cuenta, mostrando cómo debemos dirigirnos para lograr nuestro objetivo elegido.


¡Muy agradable! Muchas gracias. También gracias por agregar etiquetas apropiadas. No pude hacerlo debido a la falta de reputación. Salud.
Marc Müller

3

Supongo que usaría el hecho de que el camino generalmente se construye usando splines, por lo tanto, cada borde del camino tiene una posición de spline correspondiente, y usando eso podría determinar (aproximadamente, o de grano fino si subdivide aún más) cuál es la corriente La posición de spline de cada automóvil es, y por lo tanto, quién está a la cabeza. Entonces, más o menos de la manera que sugieres, solo usando la spline.


3

Has respondido más o menos tu propia pregunta, creo. Divida la pista en segmentos, rastree en qué segmento se encuentra cada automóvil y proyecte los automóviles en una línea a través del medio del segmento apropiado (matemáticamente es un producto de punto simple, por lo que no es complicado en absoluto). Muy simple dar a cada automóvil una "distancia" que puede ordenar por posición.

Los segmentos le brindan algunos beneficios adicionales: puede asegurarse de que los autos no corten las esquinas (o que en general tomen atajos), retrocedan u otros trucos.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.