¿Debo escribir mi propio motor de física, debido a la integración de redes?

11

Actualmente estoy desarrollando un shooter zombie de arriba hacia abajo, en tiempo real. Estoy codificando esto en Java, usando JBox2D como mi motor de física. He estado codificando la red esta semana, y ahora estoy a la altura de la sincronización física.

Estoy planeando usar el modelo predictivo de cliente / servidor autorizado, donde el cliente puede moverse libremente, siempre que el servidor lo apruebe más tarde. Esto implica que el cliente envía paquetes que contienen datos de movimiento al servidor, y el servidor calcula la latencia y vuelve a simular el mundo desde un estado anterior.

Mi problema es que mi motor de física actual, JBox2D (básicamente un puerto de Box2D), no admite la reversión del mundo, y aparentemente no es tan fácil serializar los datos mundiales. Tengo 2 soluciones, podría modificar / ampliar mi motor de física actual o escribir el mío.

Razones para escribir mi propio motor de física:

  • Puedo eliminar funciones innecesarias. En un juego de arriba hacia abajo, solo necesito mecánicas de colisión y fuerzas de manejo. No hay gravedad involucrada.
  • Puedo entender mejor el código, y [probablemente] sería más fácil implementar funciones de reversión

Razones para extender / modificar JBox2D

  • Escribir mi propio motor de física sería una gran cantidad de trabajo, que podría ser engorroso
  • JBox2D tiene una comunidad muy solidaria que me puede ayudar con mi desarrollo
  • JBox2D, tiene optimizaciones específicas, para cosas como la detección de colisiones, que lo hacen útil
  • Algunos trabajos ya se han hecho al respecto, pero se ha compartido poco código

¿Cuáles son tus opiniones? Este es mi primer juego, y no soy un desarrollador profesional de juegos. Si alguien pudiera proporcionar algunos enlaces al trabajo ya realizado en el área (preferiblemente usando JBox2D / Box2D / Java).

liamzebedee
fuente
También tenga en cuenta que si usa JBox2D, deberá usarlo en strictfptodas partes, lo que afectará seriamente el rendimiento. De lo contrario, el servidor y el cliente pueden no obtener exactamente los mismos resultados. Recomendaría usar un punto fijo en su lugar.
sam hocevar

Respuestas:

7

La detección de colisiones en 2D es tan simple que no sé por qué incluso se molestaría en usar un motor de física en primer lugar. Y dado que todas las fuerzas de manejo son directas o en una curva (sin caídas, alterando los diagnósticos, etc.) Personalmente, es una obviedad para mí lo que debes elegir. Hacer el tuyo es simple. Colisión:

cuenta las 3 posibles colisiones que pueden ocurrir en 2 rectángulos:

  1. Borde a borde: bastante simple, obtienes el eje de un solo borde, y otro y decides si ocupan el mismo espacio o lo suficientemente cerca.
  2. De borde a esquina: esto será fácilmente lo más común si tiene formas giratorias. Afortunadamente, también es bastante simple de implementar.
  3. De esquina a esquina: esto sucederá tan raramente que ni siquiera vale la pena implementarlo. La razón de esto es que 2 cosas tendrían que moverse en direcciones exactamente opuestas en el mismo eje exacto hasta el último decimal calculado de sus motores. Ahora, si todo gira 45 o 90 grados, vale la pena incluir esto (incluso probablemente no)

EDITAR: Como se comentó, estoy mucho menos familiarizado con este asunto, y no debería ser consultado sobre la colisión de bala / proyectil.

Cuando trabajé con balas en el espacio 2D, utilicé una especie de ruta que funcionó tanto en línea recta como curva donde arrojaría el proyectil usando el motor de física (que no hice desde cero) y usé la colisión estándar.

Lea sobre cómo construir esto desde cero en los comentarios.


EDITAR: * Confía en mí, * independientemente de cuál sea, necesitarás algún tipo de cálculo muerto en tu motor de juegos, debido a los proyectiles y cuántos proyectiles podrían estar en la pantalla en un momento dado. ABSOLUTAMENTE no desea actualizar cada viñeta en la pantalla por cuadro en su ubicación determinada. Pero es una excelente forma de hacer que un juego sea lento: ¡D! Solo debe actualizar estas cosas:

  • Se está lanzando un proyectil.
  • La dirección a la que se está lanzando
  • Si es curvo o no
    • Y si es así, ¿cuál es la función de la curva?
  • Qué proyectil es (esto explica el gráfico, los efectos, el daño, todo)

Ahora actualice los datos en el motor de acuerdo con esos datos, en lugar de hacerlo en el servidor para cada maldito proyectil, y envíe paquetes de datos para cada bala. (¡Imagínese hacerlo con solo 2 ametralladoras en la pantalla! ¡Jesús!)

Joshua Hedges
fuente
Por supuesto, es relativamente fácil de implementar, pero también estoy interesado en la optimización de la detección de colisiones, que no tengo idea de cómo implementar.
liamzebedee
El método que describí realmente no requerirá optimización si lo haces como se describe. La única optimización que puede ser necesaria es el tiempo que realiza las comprobaciones y con qué frecuencia se actualizan las colisiones. Por ejemplo: REALMENTE solo necesitan actualizarse cuando existe la posibilidad de colisión.
Joshua Hedges
Para ampliar lo que dije por última vez. Solo necesita verificar la colisión del edificio, por ejemplo, cuando su personaje se está moviendo en primer lugar. Solo necesita verificar la colisión de unidades, incluso cuando tiene unidades a la vista que no son su personaje. Solo necesita verificar la colisión de proyectiles, cuando incluso existen (en ese momento). Puede omitir cualquier forma de detección de tipo de colisión (¿es de borde a borde? De esquina a borde? Etc.) después de saber que algo está tocando algo más o está cerca de él. De lo contrario, omítelo en general.
Joshua Hedges
Excepto cuando estoy procesando colisiones del lado del servidor, en el que necesito detectar colisiones para múltiples jugadores, etc.
liamzebedee
44
@MadPumpkin: su exceso de confianza se refleja mal en su respuesta; estás hablando de detectar colisiones, pero no mencionas la detección de colisión de barrido que está en el núcleo absoluto del manejo adecuado de balas en un tirador 2D. Además, incluso con el barrido, la resolución es tan importante como la detección, ya que debe decidir qué colisión ocurrió primero, resolver posibles conflictos y tal vez comenzar la resolución completa nuevamente en caso de entidades eliminadas. Ciertamente no es el asunto trivial que pareces estar insinuando.
sam hocevar