Comunidad de diseño web y desarrollo en internet online

Problema con colisiones Rapidas!!!!

Citar            
MensajeEscrito el 14 Mar 2009 05:31 pm
Wenas, de antemano gracias por la atencion prestad, lo que sucede es ke ultimamemnte he estado preparando un codigo para las coliciones de un tipo de bala de ametralladora, el problema surge cuando al usar las funciones "complexHitTestObject();" y "hitTestObject( ); (de as3)" siempre obtengo el mismo resultado al itentar hacer que al menos el 95 % de las balas a una velocidad de 150ms por intervalo de disparo (no intervalo de velocdad de bala), choquen con los objetos que tengo en el esenario.

Aqui les va el code haber si alguien me puede colaborar con ese problema.

Código :

var municion:Number=6;
var shoti:Array=new Array();
var teclaCode:Number=0;

stage.addEventListener(KeyboardEvent.KEY_DOWN, presionarTecla);
function presionarTecla(event:KeyboardEvent):void 
      {if(event.keyCode==17){
               if(Retardo.bandera){
                  
                     this["shoti"+municion]=new Bala(torret.x,torret.y,torret.rotation,3);
                     //shot=new Bala(obj.torretam.x,obj.torretam.y,obj.torretam.rotation,2);guiar otra torreta
                     torret.metra.gotoAndStop(2);
                     //Smetra.play();
                     addChild(this["shoti"+municion]);
                     addEventListener(Event.ENTER_FRAME,collisionBalaM);
                     //setChildIndex(this["shoti"+municion],municion);
                     tipo=3;
                     enviar(event.keyCode+"\n");
                     if(municion<1)
                     municion=6;
                     else
                     municion--;
                     textico.text=municion.toString();
                     Retardo.vida(1);
                     
               }
            }
}
function collisionBalaM(event:Event):void
{
   for(g=1;g<=8;g++)
   {
      for(var k:Number=6;k>=1;k--)
      {
         if (HitTest.complexHitTestObject(this["shoti"+k].det,this["obs_"+g]))
         //if(shot.det.hitTestObject(this["obs_"+g]))
         {
            //impacto2(k,tipo);
            var impact:Impact=new Impact(this["shoti"+k].x,this["shoti"+k].y,torret.rotation);
         addChild(impact);
         setChildIndex(impact,3);
         var crater:Crater=new Crater(this["shoti"+k].x,this["shoti"+k].y,tipo);
         removeEventListener(Event.ENTER_FRAME,collisionBalaM);
         removeChild(this["shoti"+k]);
         addChild(crater);
         setChildIndex(crater,3);
         this["shoti"+k].simurio=true;
            
         }
      }
   }
}
Clase Retardo:

Código :

package clases
{
   import flash.display.*;
   import flash.events.*;
   import flash.utils.Timer;
   
   public class Retardo
   {
      public static var bandera:Boolean=true;
      private static var tiempo:Timer;

      public static function vida(tipo:Number=2):void
      {
         switch(tipo)
         {
            case 1:
                  tiempo=new Timer(150,1);//intervalo ametralladora
            break;
            case 2:
                  tiempo=new Timer(3000,1);//intervalo cañon tanque
            break;
         }
         bandera=false;
         tiempo.start();
         tiempo.addEventListener(TimerEvent.TIMER_COMPLETE, eliminar);
      }
      
      
      private static function eliminar(event:TimerEvent):void
      {
         bandera=true;
         tiempo.removeEventListener(TimerEvent.TIMER_COMPLETE,eliminar);
      }
   }
}
Clase Bala:

Código :

package clases{
   import flash.display.*;
   import flash.events.*;
   import flash.utils.Timer;
   import clases.*;
   dynamic public class Bala extends MovieClip 
   {
      public var simurio:Boolean=false;
      public function Bala(posx:Number,posy:Number,rot:Number,tipo:Number=1):void 
      {
         this.stop();
         this.gotoAndStop(tipo);
         this.x=posx;
         this.y=posy;
         if(tipo==3)//ametralladora
         {
            this.rotation=rot+Math.round(Math.random()*3);
            mover(3);
         }
         else
         { //cañonaso tanke
            this.rotation=rot;
            mover();
         }
         
      }
      private function mover(multi:Number=1)
      {
         var intervalo:Timer=new Timer(18/multi,60/multi-1);//20 60
         //var intervalo:Timer=new Timer(500,40);//20 60
         intervalo.addEventListener(TimerEvent.TIMER, moverYa);
         intervalo.addEventListener(TimerEvent.TIMER_COMPLETE, eliminar);

         intervalo.start();
      }
      private function moverYa(event:TimerEvent):void
      {
         var speed:Number=20;
         var angle:Number = 2*Math.PI*(this.rotation/360);
         var dx:Number=speed*Math.cos(angle);
         var dy:Number=speed*Math.sin(angle);
         this.x+=dx;
         this.y+=dy;
         //trace("moverYa()");

      }
      private function eliminar(event:TimerEvent):void
      {
         if(!simurio)
         parent.removeChild(this);//remover la bala
         removeEventListener(TimerEvent.TIMER,moverYa);
         removeEventListener(TimerEvent.TIMER_COMPLETE,eliminar);
      }
         
      /*public function eliminaYa(simurio:Boolean=true):void
      {
         
         
      }*/

   }
}
Clase de colisiones (a pixel):

Código :

package clases
{
           import flash.display.BitmapData;

              import flash.display.BlendMode;

              import flash.display.DisplayObject;

              import flash.display.Sprite;
    
              import flash.geom.ColorTransform;

           import flash.geom.Matrix;

              import flash.geom.Point;

              import flash.geom.Rectangle;

             
 
              dynamic public class HitTest

              {

       

                      public static function complexHitTestObject( target1:DisplayObject, target2:DisplayObject,  accurracy:Number = 6):Boolean

                      {

                              return complexIntersectionRectangle( target1, target2, accurracy ).width != 0;

                      }

                     

                      public static function intersectionRectangle( target1:DisplayObject, target2:DisplayObject ):Rectangle

                      {

                              // If either of the items don't have a reference to stage, then they are not in a display list

                              // or if a simple hitTestObject is false, they cannot be intersecting.

                              if( !target1.root || !target2.root || !target1.hitTestObject( target2 ) ) return new Rectangle();

                             

                              // Get the bounds of each DisplayObject.

                              var bounds1:Rectangle = target1.getBounds( target1.root );

                              var bounds2:Rectangle = target2.getBounds( target2.root );

                             

                              // Determine test area boundaries.

                              var intersection:Rectangle = new Rectangle();
  
                              intersection.x   = Math.max( bounds1.x, bounds2.x );

                              intersection.y    = Math.max( bounds1.y, bounds2.y );

                              intersection.width      = Math.min( ( bounds1.x + bounds1.width ) - intersection.x, ( bounds2.x + bounds2.width ) - intersection.x );

                              intersection.height = Math.min( ( bounds1.y + bounds1.height ) - intersection.y, ( bounds2.y + bounds2.height ) - intersection.y );

                     

                              return intersection;

                      }

                     

                      public static function complexIntersectionRectangle( target1:DisplayObject, target2:DisplayObject, accurracy:Number = 1 ):Rectangle

                      {                     

                              if( accurracy <= 0 ) throw new Error( "ArgumentError: Error #5001: Invalid value for accurracy", 5001 );

                             

                              // If a simple hitTestObject is false, they cannot be intersecting.

                              if( !target1.hitTestObject( target2 ) ) return new Rectangle();

                             

                              var hitRectangle:Rectangle = intersectionRectangle( target1, target2 );

                              // If their boundaries are no interesecting, they cannot be intersecting.

                              if( hitRectangle.width * accurracy <1 || hitRectangle.height * accurracy <1 ) return new Rectangle();

                             

                              var bitmapData:BitmapData = new BitmapData( hitRectangle.width * accurracy, hitRectangle.height * accurracy, false, 0x000000 ); 

       

                              // Draw the first target.

                              bitmapData.draw( target1, HitTest.getDrawMatrix( target1, hitRectangle, accurracy ), new ColorTransform( 1, 1, 1, 1, 255, -255, -255, 255 ) );

                              // Overlay the second target.

                              bitmapData.draw( target2, HitTest.getDrawMatrix( target2, hitRectangle, accurracy ), new ColorTransform( 1, 1, 1, 1, 255, 255, 255, 255 ), BlendMode.DIFFERENCE );

                             

                              // Find the intersection.

                              var intersection:Rectangle = bitmapData.getColorBoundsRect( 0xFFFFFFFF,0xFF00FFFF );


                              bitmapData.dispose();

                             

                              // Alter width and positions to compensate for accurracy

                              if( accurracy != 1 )

                              {

                                      intersection.x /= accurracy;

                                      intersection.y /= accurracy;
 
                                      intersection.width /= accurracy;

                                      intersection.height /= accurracy;

                              }

                             

                              intersection.x += hitRectangle.x;

                              intersection.y += hitRectangle.y;


                              return intersection;
 
                      }
 
                     
 
                     
 
                      protected static function getDrawMatrix( target:DisplayObject, hitRectangle:Rectangle, accurracy:Number ):Matrix

                      {

                              var localToGlobal:Point;;
 
                              var matrix:Matrix;
  
                             

                              var rootConcatenatedMatrix:Matrix = target.root.transform.concatenatedMatrix;

                             

                              localToGlobal = target.localToGlobal( new Point( ) );

                              matrix = target.transform.concatenatedMatrix;

                              matrix.tx = localToGlobal.x - hitRectangle.x;

                              matrix.ty = localToGlobal.y - hitRectangle.y;

                             
 
                              matrix.a = matrix.a / rootConcatenatedMatrix.a;
  
                              matrix.d = matrix.d / rootConcatenatedMatrix.d;
  
                              if( accurracy != 1 ) matrix.scale( accurracy, accurracy );
 
       

                              return matrix;
  
                      }
  
       
 
              }

       

      }



Pd: mi ortografia no es muy buena ahi perdonen.. :oops: Gracias! :)

Por PepeTV

1 de clabLevel



 

firefox
Citar            
MensajeEscrito el 16 Mar 2009 06:10 pm
Me quedo bizco con mas de 10 líneas, así que no pude llegar al final. De todas formas, si realmente quieres hacer una detección de colisión efectiva, no tienes que basarte en hitTest sino en lo que se denomina "detección predictiva", es decir en función de una trayectoria y un tiempo, calcular la siguiente (o las siguientes) posición del elemento para saber si va a colisionar o no (hitTest se basa en los FPS) Busca al respecto en gotoAndPlay.it

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 17 Mar 2009 03:35 pm
Un problema Físico :D yeeeeeeeeeeeeeeeeeeh!!!
Justo voy hacer un tip referido a colisiones o tutorial... depende de que tan extenso se me haga.
Bastante código por lo visto...
Si a tu animación le haces click derecho y seleccionas MOSTRAR REGIONES DE DIBUJO, verás la realidad del hitTestObject.
Todos son cuadrados!!! :twisted:

Hay varias formas de comprobar colisiones de las cuales recomiendo:
- Trigonometría.
- Crear tu clase Vector 2D(esta es la más interesante).

Ya estoy por terminar el tip asi que espéralo :) , pero puedes ir probando lo de las circunferencias...

Por emedinaa

196 de clabLevel

2 tutoriales

Genero:Masculino  

Lima Perú

firefox
Citar            
MensajeEscrito el 18 Mar 2009 03:18 am
Sorry si no se ve la imagen anterior (problemas con el hosting). Aquí dejo otra imagen...

Por emedinaa

196 de clabLevel

2 tutoriales

Genero:Masculino  

Lima Perú

firefox
Citar            
MensajeEscrito el 18 Mar 2009 07:46 am
Lo que Asphyk quiere hacer es "detectar colisiones basándose en la distancia". En cualquier modo, no deberíamos olvidar lo que EricLin planteó ya hace mucho mucho tiempo en su artículo The ideal collision by complex math

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 18 Mar 2009 02:50 pm
Yo no dije eso!!!, es solo una técnica y eso no quita lo de usar "x+v" en vez de solo "x", es decir adelantarse a la colision. Recomiendo lo que es con vectores matemáticos, que pretendo explicar en un tip o tutorial junto con el de "DISTANCIA"
Vectores

Por emedinaa

196 de clabLevel

2 tutoriales

Genero:Masculino  

Lima Perú

firefox
Citar            
MensajeEscrito el 18 Mar 2009 02:57 pm
Una cosilla más, en el árticulo mostrado usan DISTANCIA:

Código :

sqrt((bBall.x-rBall.x,2)^2+(bBall.y-rBall.y)^2)

Que es decir :

Código :

var D:Number=   Math.sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1)); 
//Distancia entre 2 puntos

Por emedinaa

196 de clabLevel

2 tutoriales

Genero:Masculino  

Lima Perú

firefox
Citar            
MensajeEscrito el 21 Mar 2009 03:45 am
Gracias a todos por la colaboracion!!! pero en una noche de pensar y pensar, asigne las coliciones a cada objeto que colisionaba, y no como algo en general, ya que dicha clase hittex... no es dinamica, asi que al hacerlo para cada objeto pude lograr que colisionara el 100% de los objetos, en pocas palabras, le asigne propiedad de colision a c/objeto dandoles una memoria de con que chocar y que suceder cuando choque.

Gracias!!! ^^

Por PepeTV

1 de clabLevel



 

firefox
Citar            
MensajeEscrito el 21 Mar 2009 01:51 pm
Que bueno :D , sip!!! cada partícula debe tener un sensor,como en la realidad . Te recomiendo sigas la teoría que hay en el juego de N, encontrarás técnicas como las "mallas" para optimizar las colisiones :wink:

Por emedinaa

196 de clabLevel

2 tutoriales

Genero:Masculino  

Lima Perú

firefox

 

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