检测碰撞工具类(两个类各有特点 可以结合使用)

 
package 

{

	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;

	

	public class HitTest

	{

		//========复杂(精确)碰撞测试

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

		{

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

		}

		//========返回两目标对象重叠的区域矩形

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

		{

			//如果目标对象不存在,或者简单碰撞测试为否,那么就不可能重叠

			if (! target1.root || ! target2.root || ! target1.hitTestObject(target2))

			{

				return new Rectangle;

			}

			//获取目标的边界信息Bounds

			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 (! target1.hitTestObject(target2))

			{

				return new Rectangle;

			}



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



			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);



			//绘制第一个目标

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

			//绘制第二个目标

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





			//确定位图图像中完全包含指定颜色的所有像素的矩形区域,以找到重叠区域

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



			bitmapData.dispose();

			//释放bitmapData对象的内存,返回width,height为-1;

			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

		{//返回一个转换矩阵

			//accurracy精确度

			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;

		}



	}



}

package 

{

	import flash.display.MovieClip;

	import flash.display.Sprite;

	import flash.display.BitmapData;

	import flash.display.Bitmap;

	import flash.events.MouseEvent;

	import flash.geom.*;

	import flash.filters.GlowFilter;



	public class HitTest extends MovieClip

	{

		public function HitTest()

		{

			

		}

		

		public function hitTestShape(mc1:Sprite,mc2:Sprite):Boolean

		{

			var rect1:Rectangle = mc1.getBounds(this);//这里要用rect的宽度才合适了

			//trace(this);

			var bmd1:BitmapData = new BitmapData(rect1.width,rect1.height,true,0);//返回的矩阵也是变化的

			var matrix1:Matrix = mc1.transform.matrix;

			matrix1.tx = mc1.x - rect1.x;

			matrix1.ty = mc1.y - rect1.y;

			bmd1.draw(mc1);

			var bit1:Bitmap = new Bitmap(bmd1);

			var rect2:Rectangle = mc2.getBounds(this);

			var bmd2:BitmapData = new BitmapData(rect2.width,rect2.height,true,0);

			var matrix2:Matrix = mc2.transform.matrix;

			matrix2.tx = mc2.x - rect2.x;

			matrix2.ty = mc2.y - rect2.y;

			bmd2.draw(mc2,matrix2);

			var bit2:Bitmap = new Bitmap(bmd2);

			if (bmd1.hitTest(new Point(rect1.x,rect1.y),10,bmd2,new Point(rect2.x,rect2.y),10))//可以改变透明度达到不同的检测效果

			{

				trace("碰撞了");

				mc2.filters = [new GlowFilter  ];

				return true;

			}

			else

			{

				mc2.filters = [];

			}

			return false;

		}



	}

}







package 

{

	import flash.display.*;

	import flash.geom.*;

	public class HitTest

	{

		//按照像素级别来检测碰撞

		private static function _hitTest(shape1:DisplayObject,shape2:DisplayObject):Boolean

		{

			//取得shape1和shape2的坐标

			var p1x:Number = shape1.getRect(shape1).x;

			var p1y:Number = shape1.getRect(shape1).y;

			var p2x:Number = shape2.getRect(shape2).x;

			var p2y:Number = shape2.getRect(shape2).y;

			//取得shape1和shape2的大小

			var p1w:Number = shape1.width;

			var p1h:Number = shape1.height;

			var p2w:Number = shape2.width;

			var p2h:Number = shape2.height;

			//当长宽小于1时取1

			p1w < 1 ? 1:p1w;

			p1h < 1 ? 1:p1h;

			p2w < 1 ? 1:p2w;

			p2h < 1 ? 1:p2h;

			//根据shape1和shape2的大小新建两个透明的BitmapData对象

			//Matrix(a,b,c,d,tx,ty);

			//tx:Number (default = 0) — 沿 x 轴向右平移(移动)的像素数。    

			//ty:Number (default = 0) — 沿 y 轴向下平移(移动)的像素数。 

			var BmpData1:BitmapData = new BitmapData(p1w,p1h,true,0x00000000);

			var BmpData2:BitmapData = new BitmapData(p2w,p2h,true,0x00000000);

			BmpData1.draw(shape1,new Matrix(1,0,0,1, -  p1x, -  p1y));

			BmpData2.draw(shape2,new Matrix(1,0,0,1, -  p2x, -  p2y));

			//取得shape1和shape2相对于舞台的坐标;

			//localToGlobal(point:Point):Point 将 point 对象从显示对象的(本地)坐标转换为舞台(全局)坐标。

			var gp1:Point = shape1.localToGlobal(new Point(p1x,p1y));

			var gp2:Point = shape2.localToGlobal(new Point(p2x,p2y));

			//使用BitmapData类的hitTest方法进行碰撞检测(可以根据情况设置透明度0X05)

			var re:Boolean = BmpData1.hitTest(gp1,0x05,BmpData2,gp2,0x05);

			//dispose():void 释放用来存储 BitmapData 对象的内存。

			BmpData1.dispose();

			BmpData2.dispose();

			return re;

		}

		//按照矩形区域检测碰撞

		public static function hitTestRect(shape1:DisplayObject,shape2:DisplayObject):Boolean

		{

			if (shape1.hitTestObject(shape2))

			{

				return true;

			}

			else

			{

				return false;

			}

		}

		//按照点和形状来检测碰撞

		public static function hiTestPoint(point:Point,shape:DisplayObject):Boolean

		{

			if (shape.hitTestPoint(point.x,point.y,true))

			{

				return true;

			}

			else

			{

				return false;

			}

		}

		//按形状检测

		public static function hitTestShape(shape1:DisplayObject,shape2:DisplayObject):Boolean

		{

			var hit:Boolean = false;



			if (shape1.hitTestObject(shape2))

			{

				//先用hitTestObject检测是否碰撞如果被检测的物体大小小于20那么用hitTestObject来检测直接返回true否则用像素级别检测

				if (shape2.width < 20 && shape2.height < 20)

				{

					hit = true;

				}

				else

				{

					if (HitTest._hitTest(shape1,shape2))

					{

						hit = true;

					}

				}

			}

			return hit;

		}



	}

}

/*先注意是BitmapData对象的方法hitTest(),精确到像素碰撞,
常用于判断比较大的不规则的对象碰撞,它有5个参数(前3个参数必须,后2个参数可选)依次如下(括号中是参数的类型):
firstPoint(Point):BitmapData对象的左上点的位置坐标
firstAlpha(uint):BitmapData对象中视为不透明的最高alpha通道值
secondObject(Object):碰撞的区域,可以是BitmapData对象、RectAngle对象、Point对象等。
secondBitmapDataPoint(Point):只有当secondObject参数为BitmapData对象时,才能使用该参数,表示第二个BitmapData对象的坐上点位置坐标
secondAlpha(uint):只有当secondObject参数为BitmapData对象,才能使用该参数,表示第二个BitmapData对象中视为不透明的最高alpha通道值

该碰撞没有hitTestObject()效率高,所以当对象很小时,比如宽高小于20像素,即使他不规则,采用hitTestObject()更好
*/

你可能感兴趣的:(工具类)