一个基于as3的碰撞检测类:三个参数(第一个对象:DisplayObject、第二个对象:DisplayObject、精度:Number),返回一个布尔值。。。
1 package ws.tink.display
2 {
3
4 import flash.display.BitmapData;
5 import flash.display.BlendMode;
6 import flash.display.DisplayObject;
7 import flash.display.Sprite;
8
9 import flash.geom.ColorTransform;
10 import flash.geom.Matrix;
11 import flash.geom.Point;
12 import flash.geom.Rectangle;
13
14 public class HitTest
15 {
16
17 public static function complexHitTestObject( target1:DisplayObject, target2:DisplayObject, accuracy:Number = 1 ):Boolean
18 {
19 return complexIntersectionRectangle( target1, target2, accuracy ).width != 0;
20 }
21
22 public static function intersectionRectangle( target1:DisplayObject, target2:DisplayObject ):Rectangle
23 {
24 // If either of the items don't have a reference to stage, then they are not in a display list
25 // or if a simple hitTestObject is false, they cannot be intersecting.
26 if( !target1.root || !target2.root || !target1.hitTestObject( target2 ) ) return new Rectangle();
27
28 // Get the bounds of each DisplayObject.
29 var bounds1:Rectangle = target1.getBounds( target1.root );
30 var bounds2:Rectangle = target2.getBounds( target2.root );
31
32 // Determine test area boundaries.
33 var intersection:Rectangle = new Rectangle();
34 intersection.x = Math.max( bounds1.x, bounds2.x );
35 intersection.y = Math.max( bounds1.y, bounds2.y );
36 intersection.width = Math.min( ( bounds1.x + bounds1.width ) - intersection.x, ( bounds2.x + bounds2.width ) - intersection.x );
37 intersection.height = Math.min( ( bounds1.y + bounds1.height ) - intersection.y, ( bounds2.y + bounds2.height ) - intersection.y );
38
39 return intersection;
40 }
41
42 public static function complexIntersectionRectangle( target1:DisplayObject, target2:DisplayObject, accuracy:Number = 1 ):Rectangle
43 {
44 if( accuracy <= 0 ) throw new Error( "ArgumentError: Error #5001: Invalid value for accuracy", 5001 );
45
46 // If a simple hitTestObject is false, they cannot be intersecting.
47 if( !target1.hitTestObject( target2 ) ) return new Rectangle();
48
49 var hitRectangle:Rectangle = intersectionRectangle( target1, target2 );
50 // If their boundaries are no interesecting, they cannot be intersecting.
51 if( hitRectangle.width * accuracy < 1 || hitRectangle.height * accuracy < 1 ) return new Rectangle();
52
53 var bitmapData:BitmapData = new BitmapData( hitRectangle.width * accuracy, hitRectangle.height * accuracy, false, 0x000000 );
54
55 // Draw the first target.
56 bitmapData.draw( target1, HitTest.getDrawMatrix( target1, hitRectangle, accuracy ), new ColorTransform( 1, 1, 1, 1, 255, -255, -255, 255 ) );
57 // Overlay the second target.
58 bitmapData.draw( target2, HitTest.getDrawMatrix( target2, hitRectangle, accuracy ), new ColorTransform( 1, 1, 1, 1, 255, 255, 255, 255 ), BlendMode.DIFFERENCE );
59
60 // Find the intersection.
61 var intersection:Rectangle = bitmapData.getColorBoundsRect( 0xFFFFFFFF,0xFF00FFFF );
62
63 bitmapData.dispose();
64
65 // Alter width and positions to compensate for accuracy
66 if( accuracy != 1 )
67 {
68 intersection.x /= accuracy;
69 intersection.y /= accuracy;
70 intersection.width /= accuracy;
71 intersection.height /= accuracy;
72 }
73
74 intersection.x += hitRectangle.x;
75 intersection.y += hitRectangle.y;
76
77 return intersection;
78 }
79
80
81 protected static function getDrawMatrix( target:DisplayObject, hitRectangle:Rectangle, accuracy:Number ):Matrix
82 {
83 var localToGlobal:Point;;
84 var matrix:Matrix;
85
86 var rootConcatenatedMatrix:Matrix = target.root.transform.concatenatedMatrix;
87
88 localToGlobal = target.localToGlobal( new Point( ) );
89 matrix = target.transform.concatenatedMatrix;
90 matrix.tx = localToGlobal.x - hitRectangle.x;
91 matrix.ty = localToGlobal.y - hitRectangle.y;
92
93 matrix.a = matrix.a / rootConcatenatedMatrix.a;
94 matrix.d = matrix.d / rootConcatenatedMatrix.d;
95 if( accuracy != 1 ) matrix.scale( accuracy, accuracy );
96
97 return matrix;
98 }
99
100 }
101
102 }
2 {
3
4 import flash.display.BitmapData;
5 import flash.display.BlendMode;
6 import flash.display.DisplayObject;
7 import flash.display.Sprite;
8
9 import flash.geom.ColorTransform;
10 import flash.geom.Matrix;
11 import flash.geom.Point;
12 import flash.geom.Rectangle;
13
14 public class HitTest
15 {
16
17 public static function complexHitTestObject( target1:DisplayObject, target2:DisplayObject, accuracy:Number = 1 ):Boolean
18 {
19 return complexIntersectionRectangle( target1, target2, accuracy ).width != 0;
20 }
21
22 public static function intersectionRectangle( target1:DisplayObject, target2:DisplayObject ):Rectangle
23 {
24 // If either of the items don't have a reference to stage, then they are not in a display list
25 // or if a simple hitTestObject is false, they cannot be intersecting.
26 if( !target1.root || !target2.root || !target1.hitTestObject( target2 ) ) return new Rectangle();
27
28 // Get the bounds of each DisplayObject.
29 var bounds1:Rectangle = target1.getBounds( target1.root );
30 var bounds2:Rectangle = target2.getBounds( target2.root );
31
32 // Determine test area boundaries.
33 var intersection:Rectangle = new Rectangle();
34 intersection.x = Math.max( bounds1.x, bounds2.x );
35 intersection.y = Math.max( bounds1.y, bounds2.y );
36 intersection.width = Math.min( ( bounds1.x + bounds1.width ) - intersection.x, ( bounds2.x + bounds2.width ) - intersection.x );
37 intersection.height = Math.min( ( bounds1.y + bounds1.height ) - intersection.y, ( bounds2.y + bounds2.height ) - intersection.y );
38
39 return intersection;
40 }
41
42 public static function complexIntersectionRectangle( target1:DisplayObject, target2:DisplayObject, accuracy:Number = 1 ):Rectangle
43 {
44 if( accuracy <= 0 ) throw new Error( "ArgumentError: Error #5001: Invalid value for accuracy", 5001 );
45
46 // If a simple hitTestObject is false, they cannot be intersecting.
47 if( !target1.hitTestObject( target2 ) ) return new Rectangle();
48
49 var hitRectangle:Rectangle = intersectionRectangle( target1, target2 );
50 // If their boundaries are no interesecting, they cannot be intersecting.
51 if( hitRectangle.width * accuracy < 1 || hitRectangle.height * accuracy < 1 ) return new Rectangle();
52
53 var bitmapData:BitmapData = new BitmapData( hitRectangle.width * accuracy, hitRectangle.height * accuracy, false, 0x000000 );
54
55 // Draw the first target.
56 bitmapData.draw( target1, HitTest.getDrawMatrix( target1, hitRectangle, accuracy ), new ColorTransform( 1, 1, 1, 1, 255, -255, -255, 255 ) );
57 // Overlay the second target.
58 bitmapData.draw( target2, HitTest.getDrawMatrix( target2, hitRectangle, accuracy ), new ColorTransform( 1, 1, 1, 1, 255, 255, 255, 255 ), BlendMode.DIFFERENCE );
59
60 // Find the intersection.
61 var intersection:Rectangle = bitmapData.getColorBoundsRect( 0xFFFFFFFF,0xFF00FFFF );
62
63 bitmapData.dispose();
64
65 // Alter width and positions to compensate for accuracy
66 if( accuracy != 1 )
67 {
68 intersection.x /= accuracy;
69 intersection.y /= accuracy;
70 intersection.width /= accuracy;
71 intersection.height /= accuracy;
72 }
73
74 intersection.x += hitRectangle.x;
75 intersection.y += hitRectangle.y;
76
77 return intersection;
78 }
79
80
81 protected static function getDrawMatrix( target:DisplayObject, hitRectangle:Rectangle, accuracy:Number ):Matrix
82 {
83 var localToGlobal:Point;;
84 var matrix:Matrix;
85
86 var rootConcatenatedMatrix:Matrix = target.root.transform.concatenatedMatrix;
87
88 localToGlobal = target.localToGlobal( new Point( ) );
89 matrix = target.transform.concatenatedMatrix;
90 matrix.tx = localToGlobal.x - hitRectangle.x;
91 matrix.ty = localToGlobal.y - hitRectangle.y;
92
93 matrix.a = matrix.a / rootConcatenatedMatrix.a;
94 matrix.d = matrix.d / rootConcatenatedMatrix.d;
95 if( accuracy != 1 ) matrix.scale( accuracy, accuracy );
96
97 return matrix;
98 }
99
100 }
101
102 }
一个例子:
代码如下:
1 package
2 {
3
4 import flash.display.Sprite;
5 import flash.events.MouseEvent;
6 import ws.tink.display.HitTest;
7 import flash.geom.Rectangle;
8
9 public class ComplexIntersectionRectangle extends Sprite
10 {
11
12 private var _circle0 : Sprite;
13 private var _circle1 : Sprite;
14 private var _hit : Boolean;
15 private var _intersection : Sprite;
16
17 public function ComplexIntersectionRectangle()
18 {
19 super();
20
21 initialize();
22 }
23
24 private function initialize():void
25 {
26
27 _circle0 = new Sprite();
28 _circle0.x = 50;
29 _circle0.y = 100;
30 _circle0.addEventListener( MouseEvent.MOUSE_DOWN, onCircleMouseDown );
31 draw( _circle0, 0xFFFFFF );
32 addChild( _circle0 );
33
34 _circle1 = new Sprite();
35 _circle1.x = 250;
36 _circle1.y = 100;
37 _circle1.addEventListener( MouseEvent.MOUSE_DOWN, onCircleMouseDown );
38 draw( _circle1, 0xFFFFFF );
39 addChild( _circle1 );
40
41 _intersection = new Sprite();
42 addChild( _intersection );
43
44 _hit = false;
45
46 stage.addEventListener( MouseEvent.MOUSE_MOVE, onStageMouseMove );
47 stage.addEventListener( MouseEvent.MOUSE_UP, onStageMouseUp );
48 }
49
50 private function onCircleMouseDown( event:MouseEvent ):void
51 {
52 var circle:Sprite = Sprite( event.target );
53 circle.startDrag( false );
54 }
55
56 private function onStageMouseMove( event:MouseEvent ):void
57 {
58 var intersection:Rectangle = HitTest.complexIntersectionRectangle( _circle0, _circle1, 5 );
59 var hit:Boolean = ( intersection.width > 0 && intersection.height > 0 );
60
61 _intersection.graphics.clear();
62 if( hit )
63 {
64 _intersection.graphics.beginFill( 0xFF0000, 0.5 );
65 _intersection.graphics.drawRect( intersection.x, intersection.y, intersection.width, intersection.height );
66 _intersection.graphics.endFill();
67 }
68
69 if( hit != _hit )
70 {
71 _hit = hit;
72 var color:Number = ( _hit ) ? 0x00FF00 : 0xFFFFFF;
73 draw( _circle0, color );
74 draw( _circle1, color );
75 }
76 }
77
78 private function onStageMouseUp( event:MouseEvent ):void
79 {
80 _circle0.stopDrag();
81 _circle1.stopDrag();
82 }
83
84 private function draw( circle:Sprite, color:Number ):void
85 {
86 circle.graphics.clear();
87 circle.graphics.beginFill( color, 1 )
88 circle.graphics.drawCircle( 0, 0, 25 );
89 circle.graphics.endFill();
90 }
91 }
92 }
93
2 {
3
4 import flash.display.Sprite;
5 import flash.events.MouseEvent;
6 import ws.tink.display.HitTest;
7 import flash.geom.Rectangle;
8
9 public class ComplexIntersectionRectangle extends Sprite
10 {
11
12 private var _circle0 : Sprite;
13 private var _circle1 : Sprite;
14 private var _hit : Boolean;
15 private var _intersection : Sprite;
16
17 public function ComplexIntersectionRectangle()
18 {
19 super();
20
21 initialize();
22 }
23
24 private function initialize():void
25 {
26
27 _circle0 = new Sprite();
28 _circle0.x = 50;
29 _circle0.y = 100;
30 _circle0.addEventListener( MouseEvent.MOUSE_DOWN, onCircleMouseDown );
31 draw( _circle0, 0xFFFFFF );
32 addChild( _circle0 );
33
34 _circle1 = new Sprite();
35 _circle1.x = 250;
36 _circle1.y = 100;
37 _circle1.addEventListener( MouseEvent.MOUSE_DOWN, onCircleMouseDown );
38 draw( _circle1, 0xFFFFFF );
39 addChild( _circle1 );
40
41 _intersection = new Sprite();
42 addChild( _intersection );
43
44 _hit = false;
45
46 stage.addEventListener( MouseEvent.MOUSE_MOVE, onStageMouseMove );
47 stage.addEventListener( MouseEvent.MOUSE_UP, onStageMouseUp );
48 }
49
50 private function onCircleMouseDown( event:MouseEvent ):void
51 {
52 var circle:Sprite = Sprite( event.target );
53 circle.startDrag( false );
54 }
55
56 private function onStageMouseMove( event:MouseEvent ):void
57 {
58 var intersection:Rectangle = HitTest.complexIntersectionRectangle( _circle0, _circle1, 5 );
59 var hit:Boolean = ( intersection.width > 0 && intersection.height > 0 );
60
61 _intersection.graphics.clear();
62 if( hit )
63 {
64 _intersection.graphics.beginFill( 0xFF0000, 0.5 );
65 _intersection.graphics.drawRect( intersection.x, intersection.y, intersection.width, intersection.height );
66 _intersection.graphics.endFill();
67 }
68
69 if( hit != _hit )
70 {
71 _hit = hit;
72 var color:Number = ( _hit ) ? 0x00FF00 : 0xFFFFFF;
73 draw( _circle0, color );
74 draw( _circle1, color );
75 }
76 }
77
78 private function onStageMouseUp( event:MouseEvent ):void
79 {
80 _circle0.stopDrag();
81 _circle1.stopDrag();
82 }
83
84 private function draw( circle:Sprite, color:Number ):void
85 {
86 circle.graphics.clear();
87 circle.graphics.beginFill( color, 1 )
88 circle.graphics.drawCircle( 0, 0, 25 );
89 circle.graphics.endFill();
90 }
91 }
92 }
93