[ActionScript 3.0] 像素级碰撞检测

  1 package  

  2 { 

  3     import flash.display.BitmapData; 

  4     import flash.display.BlendMode; 

  5     import flash.display.DisplayObject; 

  6     import flash.display.Sprite; 

  7     import flash.geom.ColorTransform; 

  8     import flash.geom.Matrix; 

  9     import flash.geom.Point; 

 10     import flash.geom.Rectangle;  

 11     

 12     public class HitTest 

 13     { 

 14         /**

 15          * 碰撞检测

 16          * @param    target1

 17          * @param    target2

 18          * @param    accurracy

 19          * @return  

 20          */

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

 22         { 

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

 24         } 

 25         /**

 26          * 

 27          * @param    target1

 28          * @param    target2

 29          * @return

 30          */         

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

 32         { 

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

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

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

 36             // Get the bounds of each DisplayObject. 

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

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

 39             // Determine test area boundaries. 

 40             var intersection:Rectangle = new Rectangle(); 

 41             intersection.x   = Math.max( bounds1.x, bounds2.x ); 

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

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

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

 45             return intersection; 

 46         } 

 47         /**

 48          * 

 49          * @param    target1

 50          * @param    target2

 51          * @param    accurracy

 52          * @return

 53          */

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

 55         {                      

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

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

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

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

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

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

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

 63             // Draw the first target. 

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

 65             // Overlay the second target. 

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

 67             // Find the intersection. 

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

 69             bitmapData.dispose(); 

 70             // Alter width and positions to compensate for accurracy 

 71             if( accurracy != 1 ) 

 72             { 

 73                 intersection.x /= accurracy; 

 74                 intersection.y /= accurracy; 

 75                 intersection.width /= accurracy; 

 76                 intersection.height /= accurracy; 

 77             } 

 78             intersection.x += hitRectangle.x; 

 79             intersection.y += hitRectangle.y; 

 80             return intersection; 

 81         } 

 82         /**

 83          * 

 84          * @param    target

 85          * @param    hitRectangle

 86          * @param    accurracy

 87          * @return

 88          */

 89         protected static function getDrawMatrix( target:DisplayObject, hitRectangle:Rectangle, accurracy:Number ):Matrix 

 90         { 

 91             var localToGlobal:Point;; 

 92             var matrix:Matrix; 

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

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

 95             matrix = target.transform.concatenatedMatrix; 

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

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

 98             matrix.a = matrix.a / rootConcatenatedMatrix.a; 

 99             matrix.d = matrix.d / rootConcatenatedMatrix.d; 

100             if( accurracy != 1 ) matrix.scale( accurracy, accurracy ); 

101             return matrix; 

102         } 

103     } 

104 } 

 

你可能感兴趣的:(actionscript)