マウスイベントの当たり判定で、非透明部分のみに対して反応するようにしました。
マウスイベントの当たり判定を調べるメソッド
インスタンスと座標との当たり判定を調べるには、hitTestPoint
というメソッドが使えます。
hitTestPointメソッド
hitTestPoint
メソッドの使い方は以下の通りです。
hitTestPoint(x:Number, y:Number, shapeFlag:Boolean = false):Boolean
- 第1引数(x:Number)
- このオブジェクトの検査の基準となる x 座標です。
- 第2引数(y:Number)
- このオブジェクトの検査の基準となる y 座標です。
- 第3引数(shapeFlag:Boolean)
- オブジェクトの実際のピクセルと比較して検査する場合は true、境界ボックスと比較して検査する場合は false。省略時は false。
- 戻り値(Boolean)
- 指定されたポイントと表示オブジェクトが重複または交差する場合は true、そうでなければ false。
hitTestPoint
メソッドを使った場合、第3引数の shapeFlag
で検査対象を指定できますが、この方法はシェイプデータの場合なら対処できますが、ビットマップデータの場合は、値を ture にしたとしても、透過部分も含めて交差判定の対象になります。
シェイプデータ
ビットマップデータ
これに対処するために、BitmapData
クラスの hitTest
メソッドを使います。
BitmapDataクラスのhitTestメソッド
BitmapData
クラスの hitTest
メソッドを使うと、不透明とみなされるアルファチャンネルの最小値を指定できます。
hitTest
メソッドの使い方は以下の通りです。
hitTest(firstPoint:Point, firstAlphaThreshold:uint, secondObject:Object, secondBitmapDataPoint:Point = null, secondAlphaThreshold:uint = 1):Boolean
- 第1引数(firstPoint:Point)
- 任意の座標空間における BitmapData イメージの左上隅の位置です。同じ座標空間を使って secondBitmapPoint パラメータが定義されます。
- 第2引数(firstAlphaThreshold:uint)
- このヒットテストで不透明とみなされるアルファチャンネルの最小値です。
- 第3引数(secondObject:Object)
- Rectangle、Point、Bitmap、または BitmapData オブジェクトです。
- 第4引数(secondBitmapDataPoint:Point)
- 2 番目の BitmapData オブジェクト内のピクセル位置を定義するポイントです。このパラメータは、secondObject の値が BitmapData オブジェクトである場合にのみ使用します。
- 第5引数(secondAlphaThreshold:uint)
- 2 番目の BitmapData オブジェクト内で不透明であるとみなされるアルファチャンネルの最小値です。このパラメータは、secondObject の値が BitmapData オブジェクトで、両方の BitmapData オブジェクトが透明である場合にのみ使用します。
- 戻り値(Boolean)
- ヒットが発生する場合は true、そうでない場合は false です。
アルファチャンネルの最小値を0にすることで、完全に透明なものはヒットエリアの範囲外であると判断させることができます。
BitmapData.hitTest(new Point(0,0), 0, new Point(x,y))
ビットマップの非透明部分を判定できるカスタムクラスの作成
さて、ここからが本題です。
ビットマップデータの非透明部分を判定するためには、上記で説明した hitTestPoint
メソッドを元にカスタムクラスを作成します。
hitTestPointメソッドのオーバーライド
もう少しコードを整理にするために、Sprite
クラスを継承した CustomChildクラスを作って、hitTestPoint
メソッドをオーバーライドしました。
CustomChildクラスに BitmapData
を指定して、hitTestPoint
メソッド内で BitmapData
クラスの hitTest
メソッドによる当たり判定の結果を返してます。
これによって、ビットマップの非透明部分のみでマウスイベントを受け取る事ができます。
private var _bitmap:BitmapData; private var _matrix:Matrix; private var _mapPoint:Point; private var _mousePoint:Point; public function CustomChild(bitmap:BitmapData) { _bitmap = bitmap; _matrix = new Matrix; _matrix.tx = -Math.round(bitmap.width / 2); _matrix.ty = -Math.round(bitmap.height / 2); _mapPoint = new Point(_matrix.tx, _matrix.ty); _mousePoint = new Point(0, 0); this.graphics.clear(); this.graphics.beginBitmapFill(_bitmap, _matrix, false, true); this.graphics.drawRect(_matrix.tx, _matrix.ty, _bitmap.width, _bitmap.height); this.graphics.endFill(); }
/** * 表示オブジェクトを評価して、x および y パラメーターで指定されたポイントと重複または交差するかどうかを調べます。 * @param x このオブジェクトの検査の基準となる x 座標です。 * @param y このオブジェクトの検査の基準となる y 座標です。 * @param shapeFlag オブジェクトの実際のピクセルと比較して検査する場合は true、境界ボックスと比較して検査する場合は false です。 * @return 指定されたポイントと表示オブジェクトが重複または交差する場合は true、そうでなければ false です。 */ override public function hitTestPoint(x:Number, y:Number, shapeFlag:Boolean = false):Boolean { if (shapeFlag && _bitmap != null && parent != null) { _mousePoint.x = x; _mousePoint.y = y; var p:Point = globalToLocal(_mousePoint); return _bitmap.hitTest(_mapPoint, 0, p); } else { return super.hitTestPoint(x, y, shapeFlag); } }
サンプル
ソースコードはFlashエリア上を右クリックで [View Source] からどうぞ。
- Example:ビットマップデータの不透明部分のみの当たり判定テスト