¿Quieres registrarte?

Detectar colisiones con Movie Clips de cualquier forma

Por: Zah
6 de Septiembre del 2006
3769 de clabLevel
Otros artículos de Zah
22,461 visitas

El método MovieClip.hitTest sólo permite detectar colisiones en los rectángulos de delimitación de los MovieClips. Cuando se quieren detectar colisiones con MovieClips de formas o bordes no cuadrados, se suele pensar que la única manera es usar complejas fórmulas matamáticas, aunque esto no sea viable para nosotros (Porque hay que saber muchísimas matemáticas o porque tumbaríamos el player con las operaciones).

Hay una manera alternativa de detectar colisiones que si bién no es 100% exacta, da la precisión suficiente para, por ejemplo, juegos. Como es una de esas cosas que se utilizan mucho, es altamente recomendable ponerla en un archivo .as e importarla con un #include (En mi caso pondré el siguiente código en un archivo llamado "colision.as")

Código :

function checkHit(a:MovieClip, b:MovieClip) {
   with (a) {
      if (b.hitTest(getBounds(_root).xMax, _y, true)) {
         return "left";
      } else if (b.hitTest(getBounds(_root).xMin, _y, true)) {
         return "right";
      } else if (b.hitTest(_x, getBounds(_root).yMax, true)) {
         return "up";
      } else if (b.hitTest(_x, getBounds(_root).yMin, true)) {
         return "down";
      } else {
         return false;
      }
   }
}

Esta función retorna el lado por el que han colisionado o false si no se tocan. Si sólo quieren saber si hay colisión, usen if(checkHit(a,b)!=false){...}

Analizando el código por un instante verás que el clip "a" tiene que ser el que se mueve y más pequeño. El otro, b, será la pared.

Ahora, para probarlo, creen dos clips de cualquier forma, con nombres de instancia f1 y f2 y un campo de texto llamado txt

Código :

#include "colision.as"
f1.startDrag(true);
this.onEnterFrame = function() {
   txt.text = checkHit(f1, f2);
};
Verán como en el campo de texto vemos, sin problemas, el momento en el que f1 colisiona con f2.

Enviar a twitter Enviar a facebook


También te interesa


Etiquetas actionscript

Comentarios | Enviar un comentario
Bueno, pues habrá que probarlo.. :)

Gracias!
Por: Sisco
Esto está genial :D me vendrá de perlas para según que cositas.
Por: Marc Palau_blog
Magnifico aporte Zah, es algo realmente util, no solo para juegos ^^

Gracias.. habrá que adoptarlo :)
Por: MorphX
He estado probando el código, y como dices no es del todo preciso, pero lo es suficiente para muchas cosas. Muy útil. gracias (y)
Por: Zguillez
Para super-cracks de detectar colisiones en Flash estos:
http://www.teagames.com/games

Solo hay q probar este juego:
http://www.teagames.com/games/blueprint/play.php
Por: Pepito_blog
He hallado este método muy util, muy rápido, y además "pixel-perfect" (requiere Flash 8):

http://www.gskinner.com/blog/archives/2005/10/source_code_sha.html
Por: Alan Shaw_blog
El chiste de la deteccion de colisiones no es solo detectarla, si no poder predecirla antes de que suceda. Lo cual se puede hacer con algo de trigonometria.
Por: Gerardo _blog
el _root que esta dentro del getbouds para que es?
Si quiero poner la funcion dentro de un clip tengo que cambiar la ruta esta?
Por: cam_blog

cam_blog :

el _root que esta dentro del getbouds para que es?
Si quiero poner la funcion dentro de un clip tengo que cambiar la ruta esta?

Sí, pero ten en cuenta que sólo podrás detectar la colisión de los clips hijos de ese otro clip. Si no es muy necesario, mejor no lo hagas.
Por: Zah
Excelente ya lo probé en un juego y funciona perfectamente.
Gracias.
Salu2.
Por: Taytus_blog
La forma más precisa y más rápida (a nivel de pixel) sería:
En una función o clase:
Asociar a cada MC u objeto un rectangle de sus dimensiones.
Usar rectangle.intersection para determinar si hay un rectángulo común que es lo que devuelve.
si = 0 (empty) salimos fuera
Si hay rectangulo: copiar esa zona ( tomando los datos del rectángulo respuesta de ambos mc con un draw de ese rectángulo en un bitmap que creamos temporal mediante dos threshold de transparencia y add en el segundo draw.
los 2 threshold darán un resultado numérico cada uno que se suma.
Al temporal un threshold nuevo también de zona transparente. Su valor se compara con la suma anterior.
Si son distintos: hay colisión.
Si son iguales.....todavía no hay colisión pero puede faltar poco. Recordemos que el rectángulo no es vacio.
De aquí podríamos tomar sus bounds y si el movimiento esta en ese vector (esquina de uno menos esquina del otro) ...pronto chocarán ( útil para movimientos de IA)
Como el rectángulo será siempre muy pequeño ( o empty) lo ejecutará muy rápido.
Si el objeto está girado o escalado no importa, el draw se hace con el objeto transformado.
Uffffff......Creo que hubiera tardado menos en hacerlo que en explicarlo. :crap:
Por:
jeje........ salí como invitado. No habia entrado. De todos modos, preparo el código y lo posteo....que zah lo meta en una bonita clase después.
Por: Teseo
Juas! Eso es exactamente lo que hace esta clase que ya posetearon:
http://www.gskinner.com/blog/archives/2005/10/source_code_sha.html
Por: Zah
Acabo de echarle un ojo a esa clase....
Muy similar a mi idea, aunque ese juego loco al inicio para buscar bounds mínimos yo lo simplifico con el uso de la clase rectangle que él no emplea para nada.
El no hace rectangle.intersections , llama así a una de sus variables al final.
Usa transformación de color, muchísimo más lenta que threshold y no podemos usar su respuesta numérica.
Lo que es idéntico es el concepto, pero mi forma es bastante mejor. Y en multidetecciones, muchísimo (más que muchísimo ^^ calculo del orden de una centeava parte de reloj) más rápida.
Y lo más diferente: Mi forma permite el añadir una función de detección anticipada directamente devolviendo el vector de colisión, pero en su sistema tendría que hacer 2 llamadas y cálculo posterior o externo.
Por: Teseo

Teseo :

Mi forma permite el añadir una función de detección anticipada directamente devolviendo el vector de colisión, pero en su sistema tendría que hacer 2 llamadas y cálculo posterior o externo.

:o
Justo eso me molestaba de esa clase para mi jueguecito de la webcam. Así que sí sería muy útil ^^
Por: Zah
Me contesto a mi mismo porque creo que no se entendió una cosa:
Yo intento detectar no SOLO si hay colisión entre 2 objetos sino detectar TODAS las posibles colisiones entre MC`s en escena con una sola llamada a la función. Puede hacerse un array al return de objetos que colisionan o colisionarán y sus puntos de impacto.
Por: Teseo
Hola, soi nuevo en TODO esto y me preguntaba si podrian decirme como se colisiona entre 2 movie clip paso a paso,
se que es mucho trabajo pero esque yo no se ni como importar un archovo .as
si alguno de vosotros me lo pudiera explicar se lo agradeciria de todo corazon
Por: Alex_blog
Alex tienes que poner en el panel de acciones: #include "colision.as"
o como se llame el archivo
Por: CarlosRuminott
Carlos,hize lo que me dijistes pero no me va tiene un error pero no se cual es,(les dije que soi nuevo en esto),quiero crear un juego que trate de un gato que persigue al raton y cuando lo ''atrape'' (el gato al raton) que empieze de nuevo o algo asi.Les dejo el link para que puedan ver el error y aver si pueden corregirlo

Prueba_raton.rar

Muchas gracias de antemano

link editado.MX
Por: Alex_blog
Perdon por el doble post era para decirle que copien y pegen la direccion en su barra de exploracion (el link no se ponerlo directamente)
Por: Alex_blog

Alex_blog :

Perdon por el doble post era para decirle que copien y pegen la direccion en su barra de exploracion (el link no se ponerlo directamente)


link arreglado
Por: Mariux
por favor contesten a mi pregunta
Por: Alex_blog
Deja un comentario
IMPORTANTE

Este mensaje ha sido cerrado; si deseas participar en la discusión o hablar de otro tema relacionado, hazlo en los foros de Cristalab