2004/04/23
星 鉄矢(http://www.javac.jp)

ActionScript2.0で作るフラクタル(Fractal) - Flashではどのように実装されるか

まず、実際に実装したサンプルを示します。

サンプル:SAMPLE FLASH

フラクタルを作る際に一般的に気を付けなければならないのは、何分岐まで行うかです。というのも、実装方法によっては同レベルの分岐を行う前に次の分岐に移るように組むと、無限ループに陥って、いつまで経っても全体の描画が終わらなくなるからです。また、Flashで気をつけなければならないこととして、1フレームの計算に15秒以上経過すると、FlashPlayerのアラートが出てくるからであり、また、Flashはご存知のように、本来このような数学的処理向きのソフトではありません。
ですが、Flashが再帰処理に向いていないかというと、それは全く逆です。Flashの持つMovieClipで作り上げる構造は入れ子状になっており、また、スケール変化などに関しても、入れ子の子供・孫、全てのそれ以下の階層に影響します。これは、再帰処理を実装する上で、非常に重宝できる構造です。ただ、気を付けなければならないのは、onEnterFrameや、コンストラクタで子の生成を行うと、無限ループなどが起こり、あまり深い階層まで再帰を行うことができなくなります。
これらの問題を回避するために、今回作成したのはTaskManagerクラスです。実行メソッドとその引数を登録し、TaskManagerクラスに1フレームに1回の処理をさせていきます。
Flashに特徴的なコードとして、ブラケットアクセス([ ])によるメソッドの実行があります。

method=String(methods.shift());
target=MovieClip(targets.shift());
obj=Object(params.shift());
target[method](obj);
「リファラー(Object型)[メソッド名(String型)](引数);」の形で実行すると、そのターゲットのメソッドを実行できます。addTaskメソッドで実行したいメソッドを登録し、doTaskメソッドが登録された順にメソッドを実行していきます。
また、今回のサンプルで特徴的な点として、onEnterFrameを1つしか実行していないことがあります。前述のように、生成された再帰ムービークリップがそれぞれonEnterFrameを行ってしまうと、毎フレームごとに大量のメソッドが実行されるようになり、深い階層までフラクタルを描画することができません。そこで、今回はFractalControlクラスに1つだけonEnterFrameをつくり、そこで毎フレームごとにTaskManagerクラスのdoTaskメソッドを実行しています。

private function setRunnable():Void{
    target.createEmptyMovieClip("run",1000);
    EventDispatcher.initialize(target.run);
    target.run.onEnterFrame=function(){
        var lo:Object=new Object();
        lo.target=this;
        lo.type="runnable";
        this.dispatchEvent(lo);
    }
    target.run.addEventListener("runnable",this);
}

private function stopRunnable():Void{
    target.run.removeEventListener("runnable",this);
    target.run.removeMovieClip();
}

private function runnable(){
    taskManager.doTask();
}
今回は、runという空ムービークリップを作成し、EventDispatcherを用いてonEnterFrameを実行させています。EventDispatcherを用いる利点としては、addEventListener・removeEventListenerを用いることでメソッドの実行・非実行を制御できる面があります。

(1)    (2)    (3)    (4)    (5)