Comunidad de diseño web y desarrollo en internet online

Aporte: HittestPointLiviano(x,y,mc)

Citar            
MensajeEscrito el 17 Ago 2010 10:38 am
Aca les mando algo que es muy simple y mas de uno ya lo habra hecho, pero esta bueno poder encontrarlo en un foro y no tener que programarlo uno mismo. Asi que aporto esta funcion hittest como la de flash pero mas liviana y con mas limitaciones obviamente. Es especialmente útil para hacer colisiones de balas que van muy rapido y recorren mucha distancia con muchos movieclips con los que pueden colisionar.

Limitaciones:

1) Solo se detecta colisión en el area rectangular del displayObject que se le pase como parametro
2) Solo se detecta la colisión entre un punto especificado ("x" e "y") y un movieclip, (no movieclip con movieclip)
3) El punto de registro del movieclip tiene que estar en el angulo superior izquierdo, de lo contrario hay que
improvisar una solucion que explico mas abajo en el comentario del ejemplo de uso.

¿Que tan liviano es comparado con HittestPoint con shapeFlag seteado como false (el metodo de flash para la misma tarea)?
En el ejemplo de uso que incluyo mas abajo, utilizando hittestPoint con shapeflag en false la operación tomo 13 milisegundos y en cambio con esta funcion tomo 3, es decir, es 4,3 veces mas liviana.

Modo de uso:

Código ActionScript :

trace(hittestPointLiviano(150,30,miMovieClip))  //Devuelve true o false



La funcion:

Código ActionScript :

function hittestPointLiviano(x:Number,y:Number,mc:Object):Boolean
{
   if(x > mc.x){
      if(y > mc.y){
         if(x < mc.x + mc.width){
            if(y < mc.y + mc.height){
               return true
            }
         }
      }
   }
   return false
}



Ejemplo de uso con un comentario útil para los que tienen un movieclip con un punto de registro que no esta en el angulo superior izquierdo:

Código ActionScript :

private function balaTocaPersonaje()
{
   var bala = 0;
   for (var i:int = 0; i < 970; i++)
   {
      posicionBala.x++;//Para programar una verdadera bala habria que usar trigonometría pero esto es un ejemplo simplificado
      posicionBala.y++;
      for (var j:int = 0; j < arrayPersonajes.length; j++)
      {
         //Si el punto de registro del mc que va a colisionar no esta el angulo superior izquierdo hay que
         //restarle al parametro "x" e "y" la distancia que tiene el punto de registro desde lo que seria el  
         //punto superior izquierdo
         if (hittestPointLiviano(posicionBala.x - 3,posicionBala.y - 25,arrayPersonajes[j]))
         {
            return true;
         }
      }
   }
   return false;
}



Si a alguien sabe como hacer que sea todavía mas liviana, estaría bueno que hagn un reply con el codigo.

Saludos.

Por fermmm

Claber

122 de clabLevel



 

firefox
Citar            
MensajeEscrito el 17 Ago 2010 01:01 pm
Aca les pongo otra versión que ha demostrado ser mas rapida en intervalos muy altos, pero todos los rectangulos con los que pueda llegar a colisionar tienen que ser del mismo tamaño, de lo contrario se complica más su uso. Es 2/3 mas rápida en el caso en que no se produzca colisión, su uso es diferente:

El uso consiste en hacer un "cache" de las propiedades heigth y width, ya que consultarlas cada vez es muy lento, entonces actualizé la función para que reciba dichos parametros independientemente, desde un cache.
Si los movieclips del array son de diferentes tamaños habria que hacer un cache de cada tamaño, aca va un ejemplo que funciona si todos los movieclips del array "arrayPjs" son del mismo tamaño:


Código ActionScript :

var arrayPjs:Array = [pj1, pj2 , pj3, pj4, pj5, pj6, pj7, pj8 , pj9, pj10, pj11, pj12]
var cachePjWidth:int = pj1.width
var cachePjHeight:int = pj1.height

private function balaColisiona(){
   var bala = 0
   for (var i:int = 0; i < 970; i++) 
   {
      bala++
      for (var j:int = 0; j < arrayPjs.length; j++){
         if(hittestPointLiviano(bala + 3.65 ,bala + 25.55,cachePjWidth,cachePjHeight,arrayPjs[j])){
            return true   
         }
      }
   }
   return false
}



La funcion:

Código ActionScript :

function hittestPointLiviano(x:int,y:int,Width:int,Height:int,mc:Object):Boolean
{
   var mcx:int = mc.x
   var mcy:int = mc.y
   if(x > mcx){
      if(y > mcy){
         if(x < mcx + Width){
            if(y < mcy + Height){
               return true
            }
         }
      }
   }
   return false
}

Por fermmm

Claber

122 de clabLevel



 

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.