2010-04-19 10 views
0

Je fais de petits jeux interactifs en flash pour apprendre l'AS3, maintenant j'ai rencontré un problème avec lequel j'ai besoin d'aide.comment faire la détection de collision pour les clips vidéo creux (?) Dans flash AS3?

J'ai besoin de vérifier la collision entre le lecteur et le mur qui est normalement simple en utilisant la fonction hitTestObject.

Mais maintenant j'ai fait un objet mural entourant complètement le joueur avec des couloirs et des virages, un terrain de jeu de collision pour ainsi dire. Maintenant, quand j'utilise la fonction hitTestObject pour vérifier si le joueur est en collision avec le mur, il me dit qu'il se heurte toujours soi-disant parce que l'objet joueur est dans les limites de l'objet mur.

Donc, en supposant que j'ai raison à propos de l'erreur: Comment puis-je empêcher une collision lorsque je suis à l'intérieur des limites de l'objet mural sans toucher les murs réels de cet objet?

Répondre

1

Vous aurez besoin d'utiliser une bibliothèque, j'utiliser cette classe:

package 
{ 
    import flash.display.BitmapData; 
    import flash.display.BitmapDataChannel; 
    import flash.display.BlendMode; 
    import flash.display.DisplayObject; 
    import flash.display.DisplayObjectContainer; 
    import flash.geom.Matrix; 
    import flash.geom.Point; 
    import flash.geom.Rectangle; 

    /** 
    * Use isColliding to test for a collision between two sprites. 
    * 
    * @author Troy Gilbert 
    * @author Alexander Schearer <[email protected]> 
    */ 
    public class CollisionDetection 
    { 
     /** Get the collision rectangle between two display objects. **/ 
     public static function getCollisionRect(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = true, tolerance:Number = 0):Rectangle 
     { 
      // get bounding boxes in common parent's coordinate space 
      var rect1:Rectangle = target1.getBounds(commonParent); 
      var rect2:Rectangle = target2.getBounds(commonParent); 
      // find the intersection of the two bounding boxes 
      var intersectionRect:Rectangle = rect1.intersection(rect2); 
      if (intersectionRect.size.length> 0) 
      { 
       if (pixelPrecise) 
       { 
        // size of rect needs to integer size for bitmap data 
        intersectionRect.width = Math.ceil(intersectionRect.width); 
        intersectionRect.height = Math.ceil(intersectionRect.height); 
        // get the alpha maps for the display objects 
        var alpha1:BitmapData = getAlphaMap(target1, intersectionRect, BitmapDataChannel.RED, commonParent); 
        var alpha2:BitmapData = getAlphaMap(target2, intersectionRect, BitmapDataChannel.GREEN, commonParent); 
        // combine the alpha maps 
        alpha1.draw(alpha2, null, null, BlendMode.LIGHTEN); 
        // calculate the search color 
        var searchColor:uint; 
        if (tolerance <= 0) 
        { 
         searchColor = 0x010100; 
        } 
        else 
        { 
         if (tolerance> 1) tolerance = 1; 
         var byte:int = Math.round(tolerance * 255); 
         searchColor = (byte <<16) | (byte <<8) | 0; 
        } 
        // find color 
        var collisionRect:Rectangle = alpha1.getColorBoundsRect(searchColor, searchColor); 
        collisionRect.x += intersectionRect.x; 
        collisionRect.y += intersectionRect.y; 
        return collisionRect; 
       } 
       else 
       { 
        return intersectionRect; 
       } 
      } 
      else 
      { 
       // no intersection 
       return null; 
      } 
     } 

     /** Gets the alpha map of the display object and places it in the specified channel. **/ 
     private static function getAlphaMap(target:DisplayObject, rect:Rectangle, channel:uint, commonParent:DisplayObjectContainer):BitmapData 
     { 
      // calculate the transform for the display object relative to the common parent 
      var parentXformInvert:Matrix = commonParent.transform.concatenatedMatrix.clone(); 
      parentXformInvert.invert(); 
      var targetXform:Matrix = target.transform.concatenatedMatrix.clone(); 
      targetXform.concat(parentXformInvert); 
      // translate the target into the rect's space 
      targetXform.translate(-rect.x, -rect.y); 
      // draw the target and extract its alpha channel into a color channel 
      var bitmapData:BitmapData = new BitmapData(rect.width, rect.height, true, 0); 
      bitmapData.draw(target, targetXform); 
      var alphaChannel:BitmapData = new BitmapData(rect.width, rect.height, false, 0); 
      alphaChannel.copyChannel(bitmapData, bitmapData.rect, new Point(0, 0), BitmapDataChannel.ALPHA, channel); 
      return alphaChannel; 
     } 

     /** Get the center of the collision's bounding box. **/ 
     public static function getCollisionPoint(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = false, tolerance:Number = 0):Point 
     { 
      var collisionRect:Rectangle = getCollisionRect(target1, target2, commonParent, pixelPrecise, tolerance); 
      if (collisionRect != null && collisionRect.size.length> 0) 
      { 
       var x:Number = (collisionRect.left + collisionRect.right)/2; 
       var y:Number = (collisionRect.top + collisionRect.bottom)/2; 
       return new Point(x, y); 
      } 
      return null; 
     } 

     /** Are the two display objects colliding (overlapping)? **/ 
     public static function isColliding(target1:DisplayObject, 
       target2:DisplayObject, 
       commonParent:DisplayObjectContainer, 
       pixelPrecise:Boolean = false, 
       tolerance:Number = 0):Boolean 
     { 
      var collisionRect:Rectangle = getCollisionRect(target1, target2, commonParent, pixelPrecise, tolerance); 
      if (collisionRect != null && collisionRect.size.length> 0) return true; 
      else return false; 
     } 
    } 
} 
+0

Je ne suis pas vraiment familier avec le package et les classes système de AS3. Pourriez-vous m'expliquer comment implémenter cette bibliothèque dans mon projet? – Pieter888

+0

CollisionDetection.isColliding (target1, target2, commomParent, pixelPrecise, alphaTolérance); –

1

La classe fournie par M28 est en fait une intersection et non une classe de collision (Grant Skinner a été le premier qui a fourni un retour en AS 2.0)

Vous pouvez aller avec ça pour un petit projet, mais rappelez-vous qu'il ne fait pas CCD (détection de collision continue)

cela étant dit, si est supérieure à la largeur de la paroi de la vitesse de votre lecteur vous pouvez le voir par magie passer tro sur le mur.

Si vous considérez que votre projet est plus complexe je crois que vous pouvez utiliser un moteur physique 2D qui a CCD comme Box2DFlash

http://box2dflash.boristhebrave.com/