Flash/ActionScriptチューニングの基礎知識から実践的テクニックまでを紹介する連載。読みながら試せるオンライン・サンプルもあります。Adobe AIR/Flexにも応用可能です
前回「Flashで吹雪のごとき描画を実現するチューニング3策」から、間がだいぶ空いてしまいました。完全に夏ですね。連載ペースはかなりゆったり目ですが、暖かい目で見守っていただければと思います。
さて、第3回の内容は「イベント」です。その中でも、特に多用されやすい「Event.ENTER_FRAME」「MouseEvent」のチューニングについて、紹介します。
「イベント」の仕組みは、Flashコンテンツ制作(インタラクティブコンテンツ制作全般において、というべきかもしれません)とは切っても切り離せないものです。ですが、プログラミング初心者の方が、初めにぶつかる問題でもあります。
また、使えてはいるもののイベントに関連するプロパティや、処理フローなどに関しては、実はよく分かっていないという方もいらっしゃるのではないでしょうか。
イベントに限ったことではありませんが、プログラムをチューニングするためには、その仕組みを理解し、処理の最適化や、プロパティの設定を適切に使い分けることが肝要です。前回のcacheAsBitmapも、その1つですね。
そこで今回は、簡単にイベントの仕組みを解説した後で、高速化やチューニングの考え方を解説するという流れでいこうと思います。
Flash/ActionScriptの基本については、下記記事を参照しておいてください。
いまさら聞けない! FlashとActionScriptについて
いまさら聞けないリッチクライアント技術(5) 今回は一般的にもおなじみの技術であるFlashの利点や欠点、作り方、中核技術であるActionScript、歴史などについて解説
「リッチクライアント & 帳票」フ ォーラム 2007/10/18
Flashの基礎を無料で習得! ActionScript入門
ActionScriptを知っていますか? Flash技術の要となる言語で無料で簡単にFlashアプリケーションを作れます。そのActionScriptについて初心者のために一から丁寧に解説していきます
Flash(ActionScript 3)は、どんな処理や操作が起きたかを知るために、ボタンクリック時や1フレーム進んだときなどに、その内容が逐一通知されるように、すでに作られています。ですので、コンテンツ制作者は、それらが通知されたときに何を実行するのかを決めるだけで、インタラクションが実現できます。
このように、何らかの処理要求を基点に、別の処理を行うことを「イベントドリブン(イベント駆動)」といいます。このイベントドリブンの仕組みを使うための関数が「addEventListener」です。これを使うことで「○○が起きたときに、□□を実行してくれ」という設定が簡単にできるようになっています。
もう少し具体的な話をしましょう。例えば、stage上に置かれたMovieClip(インスタンス名「mc」)の変数「x」を毎フレームで+10したいときは、以下のように書きます。
/// 毎フレームonEnterFrameを実行するように設定 mc.addEventListener( Event.ENTER_FRAME, onEnterFrame ); // 毎フレーム実行したいfunction function onEnterFrame(event:Event):void{ mc.x += 10; }
「addEventListener」は、読んで字のごとく「処理が通知されたときに(Event)、それを受けて実行されるイベントリスナ(Listener)を、追加(add)する」処理です。イベントリスナ(onEnterFrameなど)は引数が発生するイベントに対応している必要がありますが、基本的には指定したイベントのクラスが引数となります。Event.ENTER_FRAMEの場合は、Eventクラスが引数です。
また、追加(add)というくらいなので、同一のイベントタイプに複数の関数を追加できます。その際の実行順序は、基本的には追加順です。
例えば以下の場合、A→Bと実行されます(addEventListenerの第4引数のpriorityで変更可能ですが、第3引数以降の設定含め説明が複雑になり過ぎるため割愛させていただきます)。
button.addEventListener( MouseEvent.CLICK, A ); button.addEventListener( MouseEvent.CLICK, B );
追加したイベントリスナを外すときはremoveEventListenerを使います。
mc.removeEventListener( Event.ENTER_FRAME, onEnterFrame );
このように、各イベントに対してリスナを追加し、コンテンツを構築していきます。しかし、このように汎用的な仕組みは、一般的に処理負荷が高くなりがちであることに注意してください。1つ1つの処理負荷は微々たるものですが、大量のイベントを同時に扱う場合、その負荷は無視できないものとなってきます。
数あるイベントの中でも、MouseEventはイベントの伝播の仕組みを理解することが、チューニングへの近道となります。例えば、「stage上のMovieClipをクリックした際にどのような処理がなされるのか」、その処理内容を理解し適切に扱うことが重要だからです。
例えば、以下のサンプルのように、ステージに配置された要素をクリックすると、ランダムで位置が変わるものがあったとします。これの構造とイベントの伝播経路について見ていきましょう。
ステージに配置された要素をクリックするとランダムで位置が変わるFlashサンプル |
このFlashアプリの構造は以下のようになっています。このようにstageを根元として、addChildされたDisplayObject要素が枝分かれしている構造をしていることから、「DisplayObjectTree」と呼ばれています(正確には、stageの下にrootがあったりするのですが、割愛しています)
この状態でBをクリックした場合、内部では以下の経路でイベントが通知されます(実際は、「capture」「bubbling」といった概念があり、もう少し複雑です)。
処理順序としては、まずstageがMouseEventを受け取ります。次に、自分にaddChildされている各要素を調べ、発生したMouseEventを伝播すべき対象があるかを探します。今回は、Bがその対象となっているため、Bにイベントが伝播するという流れです。
また、AとBが重なった場合にBをクリックすることは基本的にはできません。重なり的に上になっているものがある場合、その要素がMouseEventを受け取るためです。
この仕組みを逆に利用し、「透明な塗りの要素をステージの最上位に追加することであらゆる要素をクリックできなくする」といった方法はよく使われているのではないでしょうか。これは、ステージの直下に透明の塗りのレイヤ(説明上は、Sheet)を置くことにより、イベントの伝播が以下のようになるからです。
普段何げなく使っているMouseEvent.CLICKなどは、このようにしてステージを基点に親から、子へと伝播していきます。普段は意識することがあまりないものですが、「最適化をする」という目的を達成するうえでは、理解しておく必要があります。
以上が、簡単なイベントの仕組みの解説です。非常にざっくりとした説明ではありましたが、なんとなくご理解いただけたのではないでしょうか。
次ページからは、これらの仕組みを基に、イベント処理や伝播経路の最適化・高速化手法の中から、筆者が特に効果があると感じた3つを紹介します。
Copyright © ITmedia, Inc. All Rights Reserved.