Sample of BitmapData.hitTest ―イレギュラーな形の衝突判定―
AdvancED ActionScript 3.0 Animation より
Bitmap for collision detection
BitmapData.hitTestメソッドのサンプル
ビットマップデータをつかってイレギュラーな形どうしの衝突判定を行う。
@author Motoki Matsumoto
/**
* Copyright mtok ( http://wonderfl.net/user/mtok )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/bRyp
*/
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;
}
}