前回の四分木 (Quad Tree) の続き
前回の四分木 (Quad Tree) の続き。
前回のデモは、衝突の可能性があるオブジェクト同士の関係を確認出来るものでしたが、今回は実際に接触しているかをチェックしています。こっちの方がイメージが湧き易いかな。
通常は灰色なオブジェクトが、他のオブジェクトに接触するとオレンジ色になります。
使い方はまたまた、今度・・・。
前回の四分木 (Quad Tree) の続き。
前回のデモは、衝突の可能性があるオブジェクト同士の関係を確認出来るものでしたが、今回は実際に接触しているかをチェックしています。こっちの方がイメージが湧き易いかな。
通常は灰色なオブジェクトが、他のオブジェクトに接触するとオレンジ色になります。
使い方はまたまた、今度・・・。
今回は四分木 (Quad Tree) について。
オブジェクト同士の衝突判定を行う際、みなさんはどうしていますか?
一番最初に思い付く方法は衝突対象のオブジェクトを配列にでも入れて、総当たりで Sprite#hitTestObject() なんかで判定してしまおうという方法だと思います。この方法でも、対象のオブジェクト数が少なければ特に問題にはなりません。しかし対象のオブジェクト数が多かった場合、総当たりで計算を行うという方法では計算量が膨大になってしまい、とても現実的とは言えません。
Sprite#hitTestObject() などの衝突判定を行う前に、どうにか衝突の可能性があるオブジェクトを限定出来ないか?
そんな時には四分木を使えば計算量が減らせます。
概念的には miscellaneous さんの「四分木」エントリーが参考になります。
四分木を構築する方法で一般的(?)なものは、空間全体をルートとし、2 x 2 の空間に分割しながらノードを構築するというもの。しかしながらこの方法、必ずしも計算量が減るわけではありません。なぜなら、衝突対象のオブジェクトを探すためにルートから該当部までノードをたどる必要があり、検索にもまた、計算コストが掛かってしまうからです。
じゃあ、どうすればいいのか?
その計算量を減らすため、四分木の構築方法は色々な方法が考え出されているようで、その中の一つに線形四分木というものがあります。概念的なものは、マルペケつくろードットコムさんの「その8 4分木空間分割を最適化する!(理屈編)」がとても参考になります。このエントリーで書いてあることもほぼ受け売りです。
で、本題。今回自作ライブラリに線形四分木用のクラスを追加しました。これを使えば、四分木がどうこう考えなくても計算対象のオブジェクトを限定することが出来ます。その限定したオブジェクトに対して Sprite#hitTestObject() なんかを行えば、計算量も下がります。
※ 描画部分は四分木とはまた別の部分なので最適化していません。あんまり円を増やしすぎると、総当たりに切り替えた時にかなり重くなりますので注意してください。
デモはキーボードで各種操作を行え、四分木 <-> 総当たりの計算量比較が出来ます。オブジェクト同士を繋ぐ線は、衝突判定が必要なことを表しています。計算量がどれだけ減ったかを確認してみて下さい。
ソースは Bitbucket に一式上げてますので、興味の有る方はどうぞ。
使い方は後日、時間がある時にでも…。
前回の UITextField に引き続き、自作ライブラリに今度は UITextArea クラスを追加しました。
前回の UITextField クラスのラッパークラスで、スクロールが可能な UI を作成できます。
扱い方はサンプル [ドキュメントコード | TextArea 実装コード ] や UITextArea の ASDoc をご覧下さい。
自作ライブラリに UITextField クラスを追加しました。
テキストフィールドのデモ(※ 要 FlashPlayer 9)
このクラスを使用して、コンポーネントでいうところの TextInput と Label が作成出来ます。標準コンポーネントでは、ダブルクリックやトリプルクリックした際のテキスト選択がおかしいですが、このクラスを使用して作成した UI では、内部で拡張したテキストフィールドを用いる事により、ダブルクリックで単語、トリプルクリックで段落を選択するように拡張されています。その他にもクリックやタブなどで最初にフォーカスが移った際にテキストを全選択する機能や、IME を制御する機能なども備えています。
詳しい扱い方はサンプル [ドキュメントコード | TextInput 実装コード | Label 実装コード ] や UITextField の ASDoc をご覧下さい。また、使ってみて変な所があれば、Issue にぜひ登録してください。
以前紹介したスクロールペインをホイール標準対応にしました。内部で JSModifier というクラスを使用することにより Mac のホイールにも標準対応しています。
今回のスクロールペインのデモ(※ 要 FlashPlayer 9)
Firefox や Opera だと前回のものは、バーやコーナーをドラッグしたまま swf の領域外に持っていった状態でマウスボタンをリリースすると、領域内に戻っても引っ付いたままになってしまっていましたが、これも JSModifier クラスによって改善されています。前回のものも掲載しておきますので、両方を試してみて下さい。
前回のスクロールペインのデモ(※ 要 FlashPlayer 9)
ちなみに JSModifier というクラスは何かというと、Mac のホイールを認識しない問題や、wmode を使用した際の不具合、その他ブラウザに起因する問題を JavaScript を用いて改善するクラスで、使い方は JSModifier.initialize(stage) するだけです。
ASDoc をアップロードしてますので、どういった問題が改善されるかなどの詳しい情報は JSModifier の項を参照して下さい。
unbland as3 library の機能で ActionScript 上で JavaScript の DOM 操作やイベントハンドリングを行う機能があります。そんな機能の紹介です。
package {
import flash.display.Sprite;
import org.unbland.core.events.JSEvent;
import org.unbland.core.external.JavaScript;
import org.unbland.core.external.JSObject;
public class Example extends Sprite
{
public function Example():void
{
// JS が利用できない環境なら終了
if (!JavaScript.enabled) {
return;
}
// JavaScript.proxy で JS 操作用のオブジェクトを取得
var document:JSObject = JavaScript.proxy.document;
var body:JSObject = document.body;
// 最初は赤色に
body.style.backgroundColor = "#FF0000";
// ドキュメント領域をクリックしたらイベントを発生させる
document.addEventListener(JSEvent.CLICK, function (e:JSEvent):void
{
// イベントが発生したら黄色に
body.style.backgroundColor = "#FFFF00";
// イベントの詳細情報をアラート
var temp:String = "";
for (var key:String in e.info) {
temp += "key : " + key + " / value : " + e.info[key] + "\n";
}
JavaScript.alert(temp);
});
}
}
}

※ 09.04.16 追記:
バージョンアップしました。くわしくは “自作ライブラリのスクロールペインをバージョンアップ” をご覧下さい。
Bitbucket に自作ライブラリを一挙に公開しました。unbland as3 library といいます。現在開発中ではありますが、公開記念に UI 作成用のクラスを紹介したいと思います。
スクロールペインのデモ(※ 要 FlashPlayer 9)
「コンポーネントを使えば?」なんて声が聞こえてきそうですが、標準のコンポーネントはスクロールのイージングに対応していなかったり、スキンのカスタマイズがものすごく面倒くさかったり、拡張性が低かったり、バグが多かったりと問題が多い(扱ったことがある方なら分かって頂けるかと思います)ので自分で実装してみました。
出来るだけ拡張性を持たせ、且つ見た目のカスタマイズなどが簡単に行えるように作成しているつもりです。具体的には、Flash IDE 上でデザインしたオブジェクトにインスタンス名を付け、抽象クラスを継承させたクラスで各種設定を記述するだけで簡単に作成出来ます。
その他にも色々な機能を実装していますので、興味の有る方は unbland as3 library Wiki をご覧になって遊んでみて下さい。サンプルなんかも置いています。今後は TextInput, TextArea, ComboBox など、最近の Flash 案件で良く使うようになってきた UI については実装していきたいなーと思っています。