Onelong

分享知识,与你一起进步......
RSS icon Home icon
  • 基于 BitmapData hitTest的碰撞检测

    post by onelong / 2010-4-2 21:16 Friday [MXML/ActionScript3.0]

    在《making things move》(flash动画基础教程)中提到了基于hitTestObject()和hitTestPoint()的碰撞,和基于距离的碰撞!这些碰撞有明显的不足,hitTestObject()只能准确的检测出矩形的碰撞,然而除了矩形外的对象它是无法准确地检测出来的!hitTestPoint()可以检测对象和某点的碰撞!然而不规则图形的碰撞检测成为难点,基于距离的碰撞检测比较适用于球体和圆形的碰撞检测!是不是对不规则图形的碰撞检测就不可以显示了呢?当然不是啦!《flash动画高级教程》就是使用了BitmapData hitTest()完美地实现不规则的碰撞,当然这种方法也有局限的!他是BitmapData的方法并不是MovieClip的方法,既然是BitmapData的方法检测位图的碰撞当然没问题了!可是如果不是位图而是影片剪辑呢?当然这不是问题!只要小作修改即可实现了!BitmapData 的draw()异常的强大!
    hitTest(firstPoint:Point, firstAlphaThreshold:uint, secondObject:Object, secondBitmapDataPoint:Point = null, secondAlphaThreshold:uint = 1)

    
    import flash.display.BitmapData;
    import flash.geom.Rectangle;
    import flash.geom.Point;
    
    var bmd1:BitmapData = 
    new BitmapData(80, 80, true, 0x00000000);
    var rect:Rectangle = new Rectangle(20, 20, 40, 40);
    bmd1.fillRect(rect, 0xFF0000FF);
    
    var pt1:Point = new Point(1, 1);
    trace(bmd1.hitTest(pt1, 0xFF, pt1)); // false
    var pt2:Point = new Point(40, 40);
    trace(bmd1.hitTest(pt1, 0xFF, pt2)); // true
    
    

    上面只是adobe帮助的一个小例子而已!BitmapData的draw方法可以从影片剪辑或sprite得到数据!这样不规则对象碰撞的实现已经成为了可能!
     

    
    package
    {
    	import flash.display.BitmapData;
    	import flash.display.Sprite;
    	import flash.display.StageAlign;
    	import flash.display.StageScaleMode;
    	import flash.events.MouseEvent;
    	import flash.filters.GlowFilter;
    	import flash.geom.Matrix;
    	import flash.geom.Point;
    	
    	public class BitmapCollision3 extends Sprite
    	{
    		private var bmpd1:BitmapData;
    		private var bmpd2:BitmapData;
    		private var star1:Star;
    		private var star2:Star;
    		
    		public function BitmapCollision3()
    		{
    			stage.align = StageAlign.TOP_LEFT;
    			stage.scaleMode = StageScaleMode.NO_SCALE;
    			
    			// make two stars, add to stage
    			star1 = new Star(50);
    			addChild(star1);
    			
    			star2 = new Star(50);
    			star2.x = 200;
    			star2.y = 200;
    			addChild(star2);
    			
    
    			bmpd1 = new BitmapData
                            (stage.stageWidth, stage.stageHeight, true, 0);			
    			bmpd2 = bmpd1.clone();
    			
    			stage.addEventListener(
                            MouseEvent.MOUSE_MOVE, onMouseMoving);
    		}
    		
    		private function onMouseMoving(event:MouseEvent):void
    		{
    			star1.x = mouseX;
    			star1.y = mouseY;
    			
    			bmpd1.fillRect(bmpd1.rect, 0);
    			bmpd2.fillRect(bmpd2.rect, 0);
    			
               
    			bmpd1.draw(star1, 
                            new Matrix(1, 0, 0, 1, star1.x, star1.y));
    			bmpd2.draw(star2, 
                            new Matrix(1, 0, 0, 1, star2.x, star2.y));
    			
    			if(bmpd1.hitTest(new Point(),255,bmpd2,new Point(),255))
    			{
    				star1.filters = [new GlowFilter()];
    				star2.filters = [new GlowFilter()];
    			}
    			else
    			{
    				star1.filters = [];
    				star2.filters = [];
    			}
    		}
    	}
    }
    Star.as;
    package
    {
        import flash.display.Sprite;
        
        public class Star extends Sprite
        {
            public function Star(radius:Number, color:uint = 0xFFFF00):void
            {
                graphics.lineStyle(0);
                graphics.moveTo(radius, 0);
                graphics.beginFill(color);
                for(var i:int = 1; i < 11; i++)
                {
                    var radius2:Number = radius;
                    if(i % 2 > 0)
                    {            
                        radius2 = radius / 2;
                    }
                    var angle:Number = Math.PI * 2 / 10 * i;
                    graphics.lineTo(Math.cos(angle) * radius2,
                    Math.sin(angle) * radius2);    
                }
            }
        }
    }
    
    

    以上例子是来源于Keith Peters《动画高级教程》

    引用地址:
     

    我要评论