PR

イベント処理でアニメーションの動きに応じた処理を追加

 最後に,Animatorクラスで利用できるイベント処理を見てみましょう。Animatorクラスでは,表3のようなイベントをハンドルできます。

表3●Animatorクラスのイベント
イベント 説明
motionStart アニメーション再生時に発生
イベント定数:MotionEvent.MOTION_START
motionEnd 再生完了時に発生
イベント定数:MotionEvent.MOTION_END
motionUpdate モーションが変更され,画面が更新された時に発生
イベント定数:MotionEvent.MOTION_UPDATE
timeChange timeが変化した時に,画面が更新される前に発生
イベント定数:MotionEvent.TIME_CHANGE

 4つのイベント共に,イベントハンドラメソッドに渡されるイベントオブジェクトは,「fl.motion.MotionEvent」です。アニメーションの再生/完了に合わせて,処理を行いたい場合には,「motionStartイベント」や「motionEnd」イベントを利用します。また,アニメーションに合わせて,エフェクト等の処理を起こしたい場合には,「motionUpdateイベント」,もしくは「timeChange」イベントを使用します。

 Animatorクラスのイベント処理を使用するには,まず,Animatorクラスのイベント処理で使用する,「fl.motion.MotionEvent」クラスが利用できるようにインポートしておきます。

import fl.motion.MotionEvent;

 あとは普通のイベント処理と変わりません。addEventListenerメソッドに,イベントの種類を表す定数と,イベント発生時に実行したい関数を指定するだけです。例えば,アニメーション開始時に発生するmotionStartイベントを利用したい場合には,次のようにコードを記述します。

Animator.addEventListener(MotionEvent.MOTION_START,関数名);

 では,早速イベント処理を利用してみましょう。今回は,飛行機の飛ぶアニメーションに合わせて,煙のエフェクトを追加してみます。

 まず,[ライブラリ]内に,煙がモクモクとアニメーションするムービークリップを作成し,クラス名を「Smoke」とします(ムービークリップを継承した埋め込みアセットクラスの作り方は,本連載第5回「表示リストで画面上のインスタンスの階層や重ね順を管理する」を参考にしてください)。

図6●ライブラリにSmokeクラスを準備する
図6●ライブラリにSmokeクラスを準備する
[画像のクリックで拡大表示]

 クラス「Smoke」の準備ができた所で,次のようにコードを記述します(クラスの作成や,モーションの作成が面倒な場合は,記事の冒頭からサンプルをダウンロードして,含まれるeventSample.flaご利用ください)。

import fl.motion.Animator;
import fl.motion.MotionEvent;
var dummy_xml:XML = <Motion 中略>中略</Motion>;
var animator:Animator = new Animator(dummy_xml,target);

//煙のアニメーションを管理する配列を用意
var smokeList:Array = [];

//アニメーション開始時の処理
animator.addEventListener(MotionEvent.MOTION_START,startHandler)
function startHandler(e:MotionEvent){
  //表示されているSmokeのインスタンスをすべて消す
  while(smokeList.length>1){
    removeChild(smokeList.pop());
  }
}

//timeの値が変化した時の処理
animator.addEventListener(MotionEvent.TIME_CHANGE,timeChangeHandler)
function timeChangeHandler(e:MotionEvent){
  //Smokeクラスのインスタンスを生成し,targetと同じ位置に表示
  var smoke:Smoke = new Smoke();
  smoke.transform.matrix = animator.target.transform.matrix;
  addChild(smoke);
  //煙の前面にtargetを再配置
  addChild(target);
  //後でまとめて消去できるように,Smokeは配列に格納しておく
  smokeList.push(smoke);
}

//アニメーションの再生
playButton.addEventListener(MouseEvent.CLICK,playAnimator)
function playAnimator(e:MouseEvent){
  animator.play();
}

図7●イベント処理を利用したサンプル・アニメーション
図7●イベント処理を利用したサンプル・アニメーション
[クリックすると別ウィンドウでムービーを表示します]

 アニメーションの開始時に発生するmotionStartイベントと,アニメーションの状態が更新された際に発生するtimeChangeメソッドを使って,指定した処理を実行できましたね。このように,Animatorクラスのイベントを利用すると,アニメーションの動きに応じた処理を簡単に追加できます。

 今回は,アニメーションの作成と制御に便利なAnimatorクラスについてご紹介しました。アニメーションの細かな制御から,いわゆる「動くメニュー」を作成する際の,ちょっとした動きのアクセントなどに利用できそうですね。次回は,キーボードの入力をActionScriptで取得して利用する方法をご紹介します。お楽しみに。

コーヒーブレイク●
モーション部分を別ファイルで管理する

 Flash CS3を使って,Animatorクラスを使用したコードを作成する際の最大の敵は,なんといってもモーションを定義するXML部分の「長さ」です。実は,Flash CS3でコードを記述する[アクション]パネルは,長いコードを書くのにはあまり適していないのです。PCの環境にもよりますが,長いコードを記述していると,すぐに何だかもっさりした動作になってしまうこともあります。

 それに,コードを見直したときに,モーション定義のXML部分に埋もれてしまって,肝心なコードを探すのが大変だったりもします。それならばと,XML部分を折りたたんでおいたのに,うっかり[自動フォーマット]ボタンを押してしまい,折りたたんでいた部分が丸見えになって涙目,なんてこともあります(筆者はよくやります)。

 このような場合には,モーションの定義部分だけ外部のファイルに書いておいて,「includeステートメント」を使って,そのファイルの内容を取り込むといった対策を取ることもできます。

 includeステートメントは,文字どおり,外部のActionScriptが記述されたテキスト・ファイルである,拡張子「*.as」形式のファイルを,をコンパイル時にActionScriptのコードとして取り込むためのステートメントです(JavaScriptのevalのように,実行時に解釈するのではない点にご注意を)。

 例えば,図8のように,任意のフォルダ内に「includeSample.as」というFlashドキュメントを作成したとします。この時,同じフォルダ内に,「motionInfo.as」という名前でテキスト・ファイルを作成し,そのファイルにモーション定義のXML情報のコード部分だけを記述し,保存します。

図8●includeステートメントの利用
図8●includeステートメントの利用

 この状態で,Flashドキュメント側でincludeステートメントを使用して

include "外部asファイルへのパス";

の形式でコードを記述すると,コンパイル時に指定した外部asファイルをそのまま読み込んで,コンパイルしてくれます。これなら,Flashドキュメント側のコードが長すぎて扱いにくい,といった事態を防ぐことができますね。

 ただし,この方法で一部のコードのみを外部asファイルに分割してしまうと,外部asファイル側で宣言した変数がどんなものなのかわからなくなったり,意図していないような処理が動いてしまったり,といったトラブルが考えられます。使用する場合にはご注意ください。

 また,すべてを外部asファイルで記述し,Flashドキュメント側はincludeするだけといったコーディングスタイルを取っている方もたくさんいます。コードを書くのは,テキストエディタなどのFlash CS3以外の環境で行っているわけですね。

 とりあえずは,includeステートメントを使用すると,「外部ASファイル」を使ったコーディングができる,ということを頭のどこかに覚えておいてください。いつか役に立つ日が来るかもしれません。