zoukankan      html  css  js  c++  java
  • 检测碰撞工具类(两个类各有特点 可以结合使用)

     
    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()更好
    */
  • 相关阅读:
    《Java TCP/IP Socket 编程 》读书笔记之十一:深入剖析socket——TCP套接字的生命周期
    c++实现二分查找
    hadoop序列化机制与java序列化机制对比
    C、C++中“*”操作符和“后++”操作符的优先级
    poj2774之最长公共子串
    Python之美[从菜鸟到高手]--urlparse源码分析
    (程序员面试题)字符串处理之寻找最大不重复子串
    hdu 4782 Beautiful Soupz
    教程Xcode 下编译发布与提交App到AppStore
    云端的ABAP Restful服务开发
  • 原文地址:https://www.cnblogs.com/602147629/p/1933083.html
Copyright © 2011-2022 走看看