Beautifl - Flash Gallery

Thumbnail : Sample of BitmapData.hitTest ―イレギュラーな形の衝突判定―
Sample of BitmapData.hitTest ―イレギュラーな形の衝突判定―
mtok 2009-10-02 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import flash.geom.Matrix;
	import flash.geom.Point;
	/**
	 * AdvancED ActionScript 3.0 Animation より
	 * Bitmap for collision detection
	 * 
	 * BitmapData.hitTestメソッドのサンプル
	 * ビットマップデータをつかってイレギュラーな形どうしの衝突判定を行う。
	 * 
	 * @author Motoki Matsumoto
	 */
	public class Main extends Sprite 
	{
		private var background:Sprite;
		private var bmp1:Bitmap;
		private var bmp2:Bitmap;
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			initStage();
			
			var radius:Number = 50;
			var s:Star = new  Star(radius, 5);
			
			var bd:BitmapData = new BitmapData(Math.ceil(s.width), Math.ceil(s.height), true, 0x00000000);
			bd.draw(s, new Matrix(1, 0, 0, 1, s.width * 0.5, radius));
			addChild(bmp1 = new Bitmap(bd));
			bmp1.x = (stage.stageWidth - bmp1.width)*0.5;
			bmp1.y = (stage.stageHeight - bmp1.height) * 0.5;
			
			bd = bd.clone();
			addChild(bmp2 = new Bitmap(bd));
		}
		private function initStage():void {
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
		}
		
		private function mouseMoveHandler(e:MouseEvent):void 
		{
			bmp2.x = mouseX - bmp1.width * 0.5;
			bmp2.y = mouseY - bmp1.height * 0.5;
			
			if (_hitTest()) {
				bmp1.filters = [new GlowFilter()];
				bmp2.filters = [new GlowFilter()];
			}else {
				bmp1.filters = [];
				bmp2.filters = [];
			}
		}
		
		private function _hitTest():Boolean
		{
			var bd1:BitmapData = bmp1.bitmapData;
			var bd2:BitmapData = bmp2.bitmapData;
			
			/*
			 * 引数1:比較するオブジェクトと同じ座標系でのビットマップデータの左上位置
			 * 引数2:比較するピクセルのアルファ値の閾値 これより小さいものは比較の対象としない。
			 * 引数3:比較対象オブジェクト、比較可能なオブジェクトはPoint Rectangle Bitmap Bitmapdata
			 * 引数4:比較対象オブジェクトがBitmapDataだった場合にBitmapdataの位置を表す座標値 左上位置
			 * 引数5:比較対象オブジェクトがBitmapDataの時のみ有効、比較するpixelのアルファ値の閾値、これより小さいものは対象としない。
			 */
			return bd1.hitTest(new Point(bmp1.x, bmp1.y), 255, bd2, new Point(bmp2.x, bmp2.y), 255);
		}
	}
	
}

import flash.display.Graphics;
import flash.display.Sprite;
import flash.geom.Point;

class Star extends Sprite {
	public function Star(r1:Number, points:int = 5, color:uint = 0xcccccc, r2:Number = Number.NaN, roundness1:Number = Number.NaN, roundness2:Number = Number.NaN){
		var deltaR:Number = 2 * Math.PI / points;
		var dr1:Number = 0;
		var dr2:Number = -deltaR * 0.5;
		
		if (isNaN(r2)) {
			r2 = r1 * 0.5;
		}
		var p1:Point = new Point(0, -r1);
		var p2:Point = rotatePoint( new Point(0, -r2), dr2);
		
		var g:Graphics = graphics;
		g.beginFill(color);
		g.moveTo(p1.x, p1.y);
		for (var i:int = 0; i < points; i++) {
			p2 = rotatePoint(p2, deltaR);
			g.lineTo(p2.x, p2.y);
			p1 = rotatePoint(p1, deltaR);
			g.lineTo(p1.x, p1.y);
		}
		g.endFill();
	}
	private function rotatePoint(p:Point, th:Number):Point {
		var _p:Point = new Point();
		var cos:Number = Math.cos(th);
		var sin:Number = Math.sin(th);
		_p.y = p.y * cos - p.x * sin;
		_p.x = p.y * sin + p.x * cos;
		return _p;
	}
}