PDA

Ver la versión completa : Detectar colisiones en movimientos rápidos



oankali
12/05/2005, 10:42
Depués de contestar a este hilo (http://www.gp32spain.com/foros/showthread.php?t=19426&page=4&pp=15) he pensado que merecía la pena abrir un hilo dedicado a este tema, o sea que aquí copio el texto.

---------------------------

Uno de los problemas de los juegos de movimiento rápido, es calibrar bien cuantas veces necesitarás comprobar la posición de un sprite durante su movimiento.

Me explico: imaginemos un juego tipo asteroides. Hay asteroides más rápidos y otros más lentos, y luego hay los disparos de la nave que van aún más rápidos.
Ahora, en medio del barullo, un pequeño asteroide de 15 píxeles de diámetro se desplaza a toda leche hacia la nave a 10 píxeles por frame. Al mismo tiempo disparamos un tiro hacia el asteroide a 15 píxeles por frame.
¿Qué pasará?
Todo depende de cómo lo hayamos programado. Si comprobamos la colisión a cada frame después de mover todos los sprites, la colisión se producirá en 60% de las veces, en el otro 40% el misil pasará a través del asteroide. ¡Coñ*!, ¿y eso porqué?
Pues porqué las velocidades suman 25 y el diámetro es de 15, que es más pequeño, con lo que puede pasar que al mover los dos sprites al mismo tiempo por saltos, se hayan cruzado sin tener nunca ningún píxel en común.
¿Cómo arreglar esto?
En este ejemplo, solo con comprobar la colisión a cada movimiento de cada sprite y no solo después de mover todos los sprites, solucionaremos el problema.
Pero si el misil va a 16 píxeles por frame aún podemos encontrarnos con el problema, aunque esta vez menos frecuentemente.
¿Cómo arreglar esto de una vez por todas?
No sé como lo hacen los otros, pero una solución es la siguiente: primero hay que calcular la distancia máxima que puede recorrer un sprite, sin que atraviese nada, por ejemplo X píxeles.
Después, a cada frame, en vez de moverlo directamente a su posición final, comprobaremos cada X píxeles en la trayectoria prevista si hay alguna colisión. Si no la hay seguimos así hasta la posición final. Si hay colisión, allí se queda el sprite.
Todo es cuestión de calcular bien X. No tiene que ser demasiado grande o nos pasaremos, ni demasiado pequeño o habrá demasiados cálculos y la velocidad del juego puede verse afectada. En principio, para juegos en que te mueves por todas las direcciones, X sería el diámetro del circulo más grande que cabe completamente en tu sprite.

Seguro que hay otros métodos, pero esto es lo que se me ha ocurrido ahora. Si tenéis otro método mejor me lo decís que estoy interesado.

Oankali

Kabal
12/05/2005, 11:22
Yo tuve un problema similar en un juego que hize "Last resort", de ese mismo tipo. De echo si alguien se fija, algunos disparos en el final boss explotan en medio del sprite y otros justo en el borde.

Una solucion que encontre fue no mover un sprite mas distacia por frame que su diametro. Por ejemplo, un disparo de 10x10 no se moveria mas de 10 pixel por frame. Pero si queremos que el disparo vaya mas rapido, sera necesario aumentar los Fps.

Otra (y esta es mas complicada) es la de distinguir entre sprites normales y de colision. Es decir, los primeros se mueven con normalidad, y los segundos calculan la colision entre frame y frame, en cada pixel que se muevan. Para el ejemplo de antes, el mismo disparo de avanzar 10 pixel tendria que calcular la colision 10 veces entre frame y frame.

Mucho me temo, que existiran muchas mas formas de programarlo. Creo que lo mejor es buscar aquel que se adapte mejor al tipo de juego.

mortimor
12/05/2005, 11:32
Yo pillo los sprites colisionables y despues de cada frame y de mover todos calculo intersecciones de trayectorias y corrijo :) no mas.