AS3.0碰撞检测 hitTestObject 与 hitTestPoint

  早先 Flash 中的影片剪辑都有内置 hitTest 方法,这个方法有很多种用途。而现在已
经将它划分为两种方法,这样做更加合理。hitTestObject 方法用于判断两个显示对象间是
否发生了碰撞,而 hitTestPoint 方法用于判断某个点与显示对象间是否发生了碰撞。

碰撞检测两个影片
    使用 hitTestObject 判断两个影片是否碰撞也许是最简单的碰撞检测方法。调用这个
函数作为影片的方法,将另一个影片的引用作为参数传入。注意,虽然我说的是影片,但这
两种方法都是 DisplayObject 类的成员,对于所有继承自显示对象类的子类, MovieClip,
                                                                     如
Bitmap, Video, TextField 等都可以使用。格式如下:
sprite1.hitTestObject(sprite2)
通常于在 if 语句中使用:
if(sprite1.hitTestObject(sprite2)) {
    // 碰撞后的动作
}
    如果两个影片发生了碰撞则返回 true,并执行 if 语句块的内容。一切事物都是把双
刃剑。碰撞检测方法越简单,其精确度就越低;相反,检测的精确度越高,则实现起来就越
复杂。因此,这个最简单的方法,精确度也是最差的。
    那么在碰撞检测中精确度意味着什么呢?不就是判断两个物体有没有冲突吗?我也希
望问题只有这么简单。
    回过头来看问题:知道两个影片的位置,如何判断它们是否碰撞?最简单的判断方法是
这样执行的:拿来一个物体,绕着它画一个矩形。再复制出一个相同的影片,两个之间进行
碰撞检测。最后判断两个矩形之间是否有相交的地方。如果有,则发生碰撞。用矩形包围物
体就是我们所熟知的矩形边界(bounding box)。当我们在 Flash IDE 中点击一个舞台元
件时,就会看到一圈蓝色的轮廓线,如图 9-1 所示。

AS3.0碰撞检测 hitTestObject 与 hitTestPoint_第1张图片

图 9-1 矩形边界
    当然,在 Flash 播放器中,并非先画上一个矩形再进行判断。一切都是根据影片的位
置和大小计算出来的。
    为什么这种方法不精确?因为,一旦两个矩形边界相交,则必然会产生碰撞。下面请见
图 9-2,这几对图形中,哪两个相交了?


AS3.0碰撞检测 hitTestObject 与 hitTestPoint_第2张图片

 

图 9-2 哪一对相交了?
    很明显,只有那两个正方形碰到了,对吧?好的,下面为它们画上矩形边界,再从 Flash
的视角观察一下。结果如图 9-3 所示。
AS3.0碰撞检测 hitTestObject 与 hitTestPoint_第3张图片

图 9-3 并非我们希望的结果
     对于 Flash 来说,每对图形是相交的。大家不相信的话,请看下面这个文档类
ObjectHitTest.as,用到了我们前面创建的 Ball 类,请确认这个类存在于类路径中:
package {
  import flash.display.Sprite;
  import flash.events.Event;
  public class ObjectHitTest extends Sprite {
   private var ball1:Ball;
   private var ball2:Ball;
   public function ObjectHitTest() {
     init();
   }
   private function init():void {
     ball1 = new Ball();
     addChild(ball1);
     ball1.x = stage.stageWidth / 2;
     ball1.y = stage.stageHeight / 2;
     ball2 = new Ball();
     addChild(ball2);
     ball2.startDrag(true);
     addEventListener(Event.ENTER_FRAME, onEnterFrame);
   }
   private function onEnterFrame(event:Event):void {
     if (ball1.hitTestObject(ball2)) {
      trace("hit");
     }
   }
  }
}
      本例创建了两个 Ball 类的实例,并将其中一个设置为可拖拽的。在每帧中使用
hitTestObject 方法判断两个影片是否发生了碰撞。注意,当我们从上,下,左,右靠近目
标时,结果都是正确的。但是如果倾斜着靠近物体,就有问题了。当然,如果物体都是矩形
的话,不会有什么问题。但物体要是越不规则,那么结果就越不准确。所以,当发生碰撞的
物体不是矩形时,大家就要格外小心。
      下面举一个使用 hitTestObject 判断矩形物体的例子。这里要用到一个崭新的 Box
类,与 Ball 类的非常相似,相信大家理解起来一定没有问题,代码如下:
package {
  import flash.display.Sprite;
  public class Box extends Sprite {
   private var w:Number;
   private var h:Number;
   private var color:uint;
   public var vx:Number = 0;
   public var vy:Number = 0;
   public function Box(width:Number=50,
   height:Number=50,
   color:uint=0xff0000) {
     w = width;
   

你可能感兴趣的:(Flex/AS3/Flash)