最近、Starlingフレームワークにおける衝突検出(Collision Detection)が扱われた学習用の英語ビデオ「Starting with Starling ー Ep 8: Collision Detection」を観ました。インスタンス同士の重なりを調べる、いくつかのやり方が紹介されています(図001)。それらをざっと眺めてみましょう。
図001■Starlingフレームワークで衝突を検出するやり方
*「Starting with Starling ー Ep 8: Collision Detection」より引用
StarlingフレームワークのDisplayObject.boundsプロパティにより、インスタンスの矩形領域(境界ボックス)を示すRectangleオブジェクトが得られます。すると、Rectangle.intersects()メソッドを使って、ふたつのRectangleオブジェクトが重なっているかどうか調べられます。
インスタンスが円形かそれに近いかたちのときは、それぞれの半径を予め定めて、ふたつの間の距離と半径の和を比べれば重なっているかどうかわかります。距離は座標をPointオブジェクトにしておけば、Point.distance()メソッドで求まります。
最適化を考えるならPoint.distance()メソッドでなく、三平方の定理で距離の2乗を求めて、半径の2乗の和と比べる方が速さは稼げるでしょう(「ActionScript 3.0 パフォーマンスチューニング - 速い、軽い、うまいスクリプティングを目指す [応用編]」01-03「距離はPointやVector3DクラスのメソッドよりMath.sqrt()で三平方の定理を使う」参照)。
簡単な多角形でしたら、各頂点座標を取出して、Rectangle.contains()メソッドで矩形領域に含まれるかどうか確かめられます。
インスタンスからBitmapDataオブジェクトが得られるなら、ActionScript 3.0定義済みのBitmapData.hitTest()メソッドでビットマップイメージのアルファまで識別した重なりが調べられます。判定は精確になるものの、処理の負荷はもっとも高くなります。
BitmapDataインスタンスと座標の重なりを確かめたスクリプトの例は、「Starlingフレームワークでビットマップ上のクリックを検知する」に紹介しました。
なお、Starling Wikiにも衝突検出を扱った記事「Basic Collision Detection」があります。サンプルスクリプトも示されているので、併せてご覧になると参考になるでしょう。また、F-siteにも最近関連する記事「StarlingフレームワークのDisplayObject.hitTest()メソッド」を書きました。興味がある方はお読みください。