Consejo rápido Detección de colisiones entre círculos

La detección de colisiones es una rama de algoritmos que verifica si dos formas se superponen. Si creas juegos de física o de acción con ActionScript, seguramente no te escaparás de este tema. Este es el primero de la serie sobre detección de colisiones. En este Consejo rápido, veremos el método de detección de colisiones incorporado de ActionScript., hitTestObject (), y escribimos el nuestro para detectar la superposición entre dos círculos..


Vista previa del resultado final

Este es el SWF final que crearemos en este Consejo rápido. Haz clic en el círculo azul y arrástralo hacia el verde. Una vez que se superponen, el círculo verde cambiará su color; Si vuelves a quitar el círculo azul, el otro volverá a ser verde..


Paso 1: Verificación de caja delimitadora

Aquellos que estén familiarizados con ActionScript 2.0 definitivamente reconocerán el método, hitTest (). Este comando verifica la superposición entre dos formas, o entre una forma y un solo punto. En ActionScript 3.0 se divide en dos métodos separados: hitTestObject () y hitTestPoint ().

Vamos a mirar hitTestObject () primero. Esta base generalmente se adapta a la detección de colisiones para formas similares a cuadros (cuadrados, rectángulos). Se dibuja un cuadro delimitador alrededor de las formas y cuando estos cuadros se superponen, hitTestObject () devuelve verdadero.

Echa un vistazo al siguiente ejemplo. Arrastra el cuadro azul hacia el verde. Cuando se superponen, la sombra de la caja verde se oscurece.

Adjunto aquí el correspondiente ActionScript que genera la presentación anterior.. Caja Es una clase escrita personalizada para generar fácilmente formas cuadradas. He incluido las clases en la carpeta de origen; hacer referencia a ellos. El guión importante para la detección de colisiones se destaca a continuación..

 paquete import flash.display.Graphics; importar flash.display.Sprite; import flash.events.MouseEvent; / ** * HitTest simple con cajas * @author Shiu * / [SWF (ancho = 400, altura = 300)] clase pública Simple extiende Sprite private var box1: Box, box2: Box; función pública Simple () box1 = new Box (0x0000FF); addChild (box1); box1.x = 250; box1.y = 250; box1.addEventListener (MouseEvent.MOUSE_DOWN, iniciar); box1.addEventListener (MouseEvent.MOUSE_UP, end); box2 = new Box (0x00FF00); addChild (box2); box2.x = 100; box2.y = 50;  inicio de función privada (e: MouseEvent): void e.target.startDrag (); e.target.addEventListener (MouseEvent.MOUSE_MOVE, verificar);  fin de la función privada (e: MouseEvent): void e.target.stopDrag (); e.target.removeEventListener (MouseEvent.MOUSE_MOVE, cheque);  verificación de función privada (e: MouseEvent): void if (e.target.hitTestObject (box2)) box2.color = 0x00AA00; else box2.color = 0x00FF00; 

Paso 2: Las deficiencias de los cuadros delimitadores

Sin embargo, la colisión entre círculos no se puede verificar de manera efectiva con este comando. Echa un vistazo a la presentación a continuación. Arrastra el círculo azul hacia el verde. Antes de que las formas choquen, sus cuadros delimitadores ya se superponen y hitTestObject () es verdad. Necesitamos una solución más precisa..

Este problema es frecuente, no solo para la detección de colisiones entre círculos, sino también para formas no cuadradas. Observe el siguiente diagrama. Para formas orgánicas que son difíciles de resolver por los polígonos, utilizaremos la detección de colisiones con precisión de píxel.


Se detectaron varias colisiones inexactas a través de hitTestObject.

Paso 3: Distancia entre centros

La solución a este problema es bastante simple: mediremos la distancia entre los centros de estos círculos. Si los centros se acercan lo suficiente, marcaremos la colisión como verdadera. Pero qué tan cerca está lo suficientemente cerca?


Distancia entre circulos.

Observe el diagrama de arriba. r1 se refiere al radio de circle1 yr2 se refiere al radio de circle2. La distancia entre círculos se calcula en cada cuadro. Si (y solo si) es igual o menor que la suma de ambos radios (r1+ r2), entonces los dos círculos deben estar tocándose o superponiéndose.


Paso 4: Detección de colisión círculo-círculo

Aquí están los ActionScript importantes para la implementación del concepto anterior:

 minDist = circle1.radius + circle2.radius;
 verificación de función privada (e: MouseEvent): void var distance: Number = Math2.Pythagoras (circle1.x, circle1.y, circle2.x, circle2.y); si (distancia) <= minDist) circle2.color = 0x00FFAA; else circle2.color = 0x00FF00; 

Paso 5: Solución de muestra

Aquí hay una muestra de la solución. Arrastra el círculo azul hacia el verde. A medida que se superponen, verás un cambio de color verde. Vuelve a la normalidad cuando ambos círculos no chocan..

He incluido la implementación de ActionScript a continuación.

 paquete import flash.display.Sprite; import flash.events.MouseEvent; / ** * Colisión simple entre 2 círculos * @author Shiu * / [SWF (ancho = 400, altura = 300)] clase pública Simple3 extiende Sprite private var circle1: Circle, circle2: Circle; privado var minDist: Number; función pública Simple3 () circle1 = new Circle (0x0055AA, 30); addChild (circle1); circle1.x = 250; circle1.y = 250; circle1.addEventListener (MouseEvent.MOUSE_DOWN, inicio); circle1.addEventListener (MouseEvent.MOUSE_UP, end); circle2 = new Circle (0x00FF00, 30); addChild (circle2); circle2.x = 100; circle2.y = 50; minDist = circle1.radius + circle2.radius;  inicio de función privada (e: MouseEvent): void e.target.startDrag (); e.target.addEventListener (MouseEvent.MOUSE_MOVE, verificar);  fin de la función privada (e: MouseEvent): void e.target.stopDrag (); e.target.removeEventListener (MouseEvent.MOUSE_MOVE, cheque);  verificación de función privada (e: MouseEvent): void var distance: Number = Math2.Pythagoras (circle1.x, circle1.y, circle2.x, circle2.y); si (distancia) <= minDist) circle2.color = 0x00FFAA; else circle2.color = 0x00FF00;   

Conclusión

Como puede ver, el principio general de la detección de colisiones es utilizar fórmulas matemáticas para verificar las superposiciones entre diferentes formas. Las matemáticas vectoriales también juegan un papel importante. Lo próximo que viene es la colisión entre un círculo y una línea. Gracias por leer y hasta pronto..