Recientemente aprendí monogame y estoy trabajando en un juego simple de arriba hacia abajo para comenzar y aprender los conceptos básicos.
Tengo el movimiento y la rotación para seguir el mouse, pero estoy atrapado en las colisiones.
Lo que quiero saber, básicamente, son dos cosas:
- ¿Cuál sería la mejor manera de manejar las colisiones? Sé que
Rectangle.Intersects(Rectangle1, Rectangle2)
devuelve el rectángulo superpuesto, pero, como el movimiento de arriba hacia abajo está en el eje x / y, me gustaría saber dónde está ocurriendo la colisión para poder crear una especie de "deslizamiento de la pared" donde el jugador no consigue pegado a la pared.
¿Verificación de las coordenadas x / y de los jugadores contra las coordenadas de objetos sólidos, luego lanzar al jugador a su posición anterior si entra en los límites de un objeto sólido realmente el mejor enfoque? ¿Qué sugieres? - ¿Cuál sería la mejor manera de aplicar colisiones a todos los sólidos, npc, etc.? Actualmente estoy pensando en crear una
gameObject
clase de la que todos los objetos heredarán y solo manejarán las colisiones allí.
Gracias por leer y espero que alguien pueda darme algunos consejos.
xna
c#
collision-detection
collision-resolution
monogame
Eliah John
fuente
fuente
Respuestas:
En general, la forma en que la mayoría de los motores de física manejan este problema es separando los objetos que se cruzan .
Entonces, si sus objetos están representados por rectángulos (también conocidos como "Cajas delimitadas por ejes alineados"), y colisionan en un marco dado de la siguiente manera:
Luego mediría la cantidad de interpenetración en cada eje. Luego seleccione el eje con la menor cantidad de interpenetración y separe los objetos a lo largo de ese eje.
Luego registraría esto como una "colisión" y aplicaría la dinámica apropiada.
Por ejemplo, si desea deslizarse a lo largo de la pared, simplemente reduciría a cero la velocidad en el eje en el que se separó (el eje X, en la ilustración de arriba), dejando solo la velocidad en el otro eje.
Pero también podrías aplicar fricción o hacer que los objetos reboten.
Aquí hay un excelente tutorial interactivo que muestra cómo hacer esto con mucho más detalle.
Sin embargo, si va a ir por este camino (algo más que simples colisiones AABB), es posible que desee considerar el uso de un motor existente como Farseer Physics .
Finalmente, una nota sobre la implementación (si no sigue la ruta Farseer):
Rectangle
utilizaint
valores, que en la mayoría de los casos no son realmente apropiados para hacer física. Considere hacer su propiaAABB
clase que use en sufloat
lugar.Su segunda pregunta está bastante bien respondida por mi antigua respuesta sobre la arquitectura del juego aquí , así que no la repetiré aquí.
fuente
1: También he estado trabajando en un juego de acción de arriba hacia abajo relativamente simple, y después de una semana (-s?) De lucha, terminé usando una especie de enfoque paso a paso para la detección y respuesta de colisiones. La razón principal es que el uso de la menor cantidad de interpenetración resultaría en algunos casos en "teletransportación" a una nueva posición en la que el objeto en movimiento no estaba previamente.
entonces, cuando un objeto quiere moverse,
Este enfoque garantiza que el objeto "rebote" para corregir la posición anterior y permite deslizarse contra las paredes, los objetos, lo que sea.
2: Yo mismo uso una clase de colisión estática que puede ser utilizada por lo que sea. contiene métodos de detección de colisión y ajuste de vectores, que pueden ser llamados por casi cualquier cosa. si estos métodos se llaman desde una clase de juego "maestra" o por alguna subclase de objeto no importa realmente en mi caso, porque la clase de colisión crea una nueva lista en cada cuadro para todos los rectángulos con los que se cruza el objeto en movimiento. Estos rectángulos pueden ser de azulejos, decoraciones, NPC, lo que sea que tenga límites y sea colisionable, básicamente. Esto significa que la necesidad de todos los objetos del juego que son colisionables es tener límites rectangulares. si tienen eso, la clase de colisión se encargará del resto.
Espero que esto sea comprensible.
fuente
1: Utilicé con éxito una técnica para resolver esto: usando la velocidad y la posición puedes descubrir la colisión e iterar hacia atrás hasta que la posición esté muy cerca del punto de colisión exacto.
No es parte de la respuesta a su primera pregunta, pero si tiene muchos objetos que pueden chocar entre sí, debe usar cuadrúpedos para mejorar el rendimiento. Hay un muy buen tutorial con muchos ejemplos aquí .
2: siempre recomiendo Entity-Systems .
fuente