前回は,ActionScript3.0でのイベント処理の作成方法の基本を紹介しました。今回は,イベント処理の中でも,特に使う機会の多い,画面上の物に対するイベント処理について詳しく説明します。

 ActionScript3.0では,画面上に表示されている物をマウスやキーボードで操作する際のイベントに,わかりやすいイベント伝達の流れの仕組みが取り入れられました。「表示リスト」の仕組みと合わせて,この「イベントフロー」を整理してみましょう。

 図1は,二つのウィンドウの中に,一つのボタンと,一つの猫のアニメーションのインスタンスが配置してあります。ウィンドウはドラッグすると位置を移動できます。また,アニメーションのインスタンスは,インスタンスをクリックすると,移動の方向を転換し,ボタンを押すと,ジャンプします。

図1●階層構造のあるインスタンスのイベント
図1●階層構造のあるインスタンスのイベント
[画像のクリックでサンプルを表示]

 このような,「入れ子」「階層構造」を持つインスタンス間には,表示リストに基づいた,独特のイベントフローを持ちます。このイベントフローの仕組みを知っておくと,階層構造を持つインスタンスのイベントの管理が非常に楽になります。

階層構造を持つインスタンスのイベント処理を作成してみよう

 ActionScript3.0では,画面上に表示されている物を,表示リストで管理していることは,第5回に説明しましたね。ActionScript3.0では,イベント処理を,この表示リストに基づいた「順序」で伝達しています。

 具体的な例を使って,その仕組みを見てみましょう。図2のような構成のFlashムービーを作成したとします。

図2●階層構造を持ったムービー
図2●階層構造を持ったムービー

 stageと,メインのタイムラインの下に,インスタンス「window」が配置されています。さらに,windowには,「button1」「button2」「button3」の三つのボタン・インスタンスが配置してあります。

 このとき,メインのタイムラインに次のようにコードを記述してみます。内容は,button1をクリックしたら,イベントオブジェクトのtargetプロパティ経由でクリックしたインスタンスを取得し,nameプロパティでインスタンス名を表示する,というものです。

//クリック時に実行する関数
function onClick(e:MouseEvent){
  trace(e.target.name + "をクリックしました");
}
//button1に関数を関連付ける
window.button1.addEventListener(MouseEvent.CLICK,onClick);

 インスタンスの準備と,コードの記述が終わったら,ムービープレビューで結果を確認してみましょう(*1)。

 button1をクリックすると,図3のようなメッセージが表示されますね。念のためbutton2やbutton3を押してみても,なにもメッセージは表示されません。

図3●クリックしたインスタンスの名前を表示する
図3●クリックしたインスタンスの名前を表示する

 では,button2やbutton3にも,clickイベント発生時に同じ処理を実行させてみましょう。あなたならどんなコードを記述しますか? まず最初に思いつくのは,button2,button3の一つひとつにbutton1と同じようにaddEventListenerメソッドを使用して,イベントと関数を関連付ける方法でしょう。

//クリック時に実行する関数
function onClick(e:MouseEvent){
  trace(e.target.name + "をクリックしました");
}
//button1~button3に関数を関連付ける
window. button1.addEventListener(MouseEvent.CLICK,onClick);
window. button2.addEventListener(MouseEvent.CLICK,onClick);
window. button3.addEventListener(MouseEvent.CLICK,onClick);

 このコードをムービープレビューで実行すると,意図通りに,button1~button3をクリックすると,ボタンに応じたインスタンス名が表示されます。最も正統派の処理です(図4)。

図4●複数のボタンのインスタンス名を知る
図4●複数のボタンのインスタンス名を知る

 ではここで,イベントフローを利用した処理を記述してみましょう。今まではイベントの発生元である各ボタンに対してaddEventListenerメソッドを使っていましたが,今度は,その上の階層であるインスタンス「window」に対して,addEventListenerメソッドを使います。

//クリック時に実行する関数
function onClick(e:MouseEvent){
  trace(e.target.name + "をクリックしました");
}
//button1~button3の上位の階層であるwindowに関数を関連付ける
window.addEventListener(MouseEvent.CLICK,onClick);

 「ボタンの処理なのに,どうしてその上のムービークリップ・インスタンスにイベント処理を割り当てるんだろう?」と思うかもしれません。でも,ここはとりあえずムービープレビューで結果を確認してみましょう。

 ムービープレビューを行い,button1~button3,そして,ボタンの配置していないwindowの任意の個所をクリックしてみてください。すると,結果は図5のようになります。各ボタンをクリックした場合には,ボタン名が,そして,ボタンの無い個所をクリックした場合には,「window」とインスタンス名が表示されますね。

図5●上位の階層でイベントを拾う
図5●上位の階層でイベントを拾う

 イベント処理は,windowにしか割り当て無かったはずです。どうしてこのような結果になったのでしょうか。これは,ActionScript3.0から採用されたイベントフローの仕組みによるものです。