Flash+actionScript 3.0: BitmapData의 충돌 테스트.

별 모양의 무비클립들을 마우스로 드래그가 가능하며 일반적 충돌체크와 비트맵 데이터 충돌체크를 각각 실행한다.
일반적 충돌체크인 hitTestObject의 경우 Object를 둘러싼 사각형의 경계박스를 기준으로 충돌 검사를 하기에 별같은 모양일 경우 보이는 것과 실제 충돌 처리가 되는 것 사이에 간극이 있다. 반면 비트맵 데이터 충돌 검사의 경우 픽셀 단위로 체크하기에 보이는 대로 처리가 되어 정밀한 충돌체크가 가능하지만 계산량이 많아 CPU 사용률이 상대적으로 높아진다.

액션스크립트 3.0이 제공하는 충돌체크는 기본적으로 3가지.
1. 두개의 Object 사이의 충돌: Sprite1.hitTestObject(Sprite2)
2. Object와 점 사이의 충돌: Sprite1.hitTestPoint(x, y, shapeFlag(true/false)) -shapeFlag를 true로 설정하면 경계박스가 아닌 시각적인 그래픽 부분과의 충돌을 체크한다.
3. 두개의 BitmapData 사이의 충돌: bitmapData1.hitTest(Point, alpha, bitmapData2, Point, alpha)

비트맵 데이터 충돌체크는
aBmpData.hitTest(new Point(a.x, a.y), 255, bBmpData, new Point(b.x, b.y), 255)
형태이며 (충돌을 검사할 비트맵 데이터의 좌측 상단, 알파채널, 충돌대상 비트맵 데이터의 좌측 상단, 알파채널)로 구성된다.

14/7/21 월

참고한 웹 페이지(영문):
http://www.mikechambers.com/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/
첫번째 예제는 일반적인 Bitmap.hitTest(),
두번째 예제는 회전하는 물체에대한 Bitmap.hitTest()를 다루고 있다.
(일반적으로 Bitmap.hitTest()는 고정된 상태에 적용되는데 반해 두번째 예제의 경우 transform.matrix를 이용해 변화하는 상태에 적용가능하게 하고 있다. )

function init(){
     star1.addEventListener(MouseEvent.MOUSE_DOWN, mDown);
     star1.addEventListener(MouseEvent.MOUSE_UP, mUp);
     star2.addEventListener(MouseEvent.MOUSE_DOWN, mDown);
     star2.addEventListener(MouseEvent.MOUSE_UP, mUp);
     stage.addEventListener(Event.ENTER_FRAME, loop);
}
function mDown(e:MouseEvent){
     //누른 무비클립을 맨 위로.
     e.currentTarget.parent.setChildIndex(e.currentTarget, 
				e.currentTarget.parent.numChildren-1);
     e.currentTarget.startDrag();
}
function mUp(e:MouseEvent){
     e.currentTarget.stopDrag();
}
function loop(e:Event){
     collisionTest(star1, star2);
     collisionTestBitmap(star1, star2);
}

function collisionTest(a, b){ //일반적 충돌체크
     if(a.hitTestObject(b)){
          a.gotoAndStop(2);
     }else{
          a.gotoAndStop(1);
     }
}

function collisionTestBitmap(a, b){ //bitmapData 충돌체크
var aRect:Rectangle = a.getBounds(this);
var aBmpData = new BitmapData(aRect.width, aRect.height, true, 0);
aBmpData.draw(a);

var bRect:Rectangle = b.getBounds(this);
var bBmpData = new BitmapData(bRect.width, bRect.height, true, 0);
bBmpData.draw(b);

    if(aBmpData.hitTest(new Point(a.x, a.y),
                                255,
                                bBmpData,
                                new Point(b.x, b.y),
                                255)){
        b.filters = [new GlowFilter()];
        b.gotoAndStop(3);
    }else{
        b.filters = [];
        b.gotoAndStop(1);
    }
}

init();