ActionScript 3.0で始めるオブジェクト指向スクリプティング

第30回 マウスイベントとインスタンスの兄弟・親子の関係

この記事を読むのに必要な時間:およそ 3 分

マウスイベントが発生するインスタンスとそれを処理するインスタンス

前節では,いくつかのインスタンスが同じ階層にある兄弟の関係のとき,マウスイベントを誰が受け取るかについて考えた。しかし,Flashの DisplayObjectインスタンスは,入れ子の階層構造つまり親子の関係になることも多い。つぎは,この場合のマウスイベントについて説明しよう。

イベントリスナーの関数は,引数にイベントオブジェクトを受け取った。このイベントオブジェクトのEvent.targetプロパティを調べると,イベントを受け取ったインスタンスがわかる。たとえば,前述のスクリプトと同じムービーでリスナー関数をつぎのように書替えれば,ボタンをクリックしたとき,インスタンスの文字列表現とインスタンス名が[出力]される図6⁠。

// タイムライン: メイン
// MovieClipインスタンスbutton_mcを配置
// フレームアクション
button_mc.addEventListener(MouseEvent.CLICK, xTrace);
function xTrace(eventObject:MouseEvent):void {
  var myTarget:DisplayObject = eventObject.target as DisplayObject;
  trace(myTarget, myTarget.name);
}

図6 Event.targetプロパティでイベントを受取ったインスタンスとその名前を[出力]

図6 Event.targetプロパティでイベントを受取ったインスタンスとその名前を[出力]

ここで,Event.targetプロパティの値に対して,as演算子を使った。この演算子は,データ型を評価し直す。

式 as データ型

Event.targetプロパティにはさまざまなデータ型の値が入るので,戻り値はObject型で指定されている。しかし,それではDisplayObject型の変数(myTarget)に代入できず,DisplayObject.nameプロパティにもアクセスできない。as演算子により,Event.targetプロパティの戻り値をDisplayObject型のデータに評価し直し,DisplayObject型の変数に代入できるようになるのだ。

さてそれでは,入れ子の親子関係をつくるため,ボタンの MovieClipシンボル内にMovieClipインスタンスをひとつ置く。そして,入れ子のインスタンスにはpen_mcと名前をつけた図7⁠。もちろん,子インスタンスpen_mcには,名前以外のスクリプトなどは一切設定しない。

図7 ボタンのMovieClipシンボル内にMovieClipインスタンスをひとつ置く

図7 ボタンのMovieClipシンボル内にMovieClipインスタンスをひとつ置く

つぎに,メインタイムラインには,以下のフレームアクションを記述する。先ほど試したスクリプトや前掲スクリプト1とはイベントリスナーの登録先が変わり,EventDispatcher.addEventListener()メソッドはDisplayObject.stageプロパティを参照している。

// タイムライン: メイン
// MovieClipインスタンスbutton_mcを配置
// フレームアクション
stage.addEventListener(MouseEvent.CLICK, xTrace);
function xTrace(eventObject:MouseEvent):void {
  var myTarget:DisplayObject = eventObject.target as DisplayObject;
  trace(myTarget, myTarget.name);
}

StageオブジェクトにInteractiveObject.clickイベントのリスナーを登録したので,ステージの何もないところをクリックしてもリスナー関数は呼び出される図8上図⁠。Stageオブジェクトにインスタンス名はないので,DisplayObject.nameプロパティの[出力]はnullだ。さてところが,ボタンのインスタンスbutton_mcやその入れ子のインスタンスpen_mcをクリックすると,Event.targetプロパティの値としてそれらのインスタンスの情報が[出力]パネルに表示される図8中下図⁠。

図8 クリックしたインスタンスがマウスイベントを受取ってリスナー関数が呼び出される

図8 クリックしたインスタンスがマウスイベントを受取ってリスナー関数が呼び出される

ステージをクリック

画像

ボタンのインスタンス(button_mc)をクリック

画像

ボタンの入れ子のインスタンス(pen_mc)をクリック

マウスイベントのリスナーは,Stageオブジェクトにしか登録していない。それでもリスナー関数が呼び出されるのは,マウスイベントそのものはクリックされたインスタンスが受け取っても,イベントの発生は親のインスタンスにも伝えられるからだ。つまり,マウスイベントは子から親に伝わり,子に発生したイベントは親が処理できる※2⁠。

イベントを処理しているインスタンスは,Event.currentTargetプロパティで調べられる。上記のフレームアクションにこのプロパティ値の[出力]を加えたのが,以下のスクリプト2だ。クリックするインスタンスを変えても,このEvent.currentTargetプロパティはつねにイベントリスナーが呼出されているインスタンスを返す。

// ステージをクリック
[object Stage] null [object Stage]
// ボタンのインスタンス(button_mc)をクリック
[object Button_1] button_mc [object Stage]
ボタンの入れ子のインスタンス(pen_mc)をクリック
[object MovieClip] pen_mc [object Stage] 

スクリプト2 マウスイベントが発生したインスタンスと処理するインスタンスを[出力]する

// タイムライン: メイン
// MovieClipインスタンスbutton_mcを配置
// フレームアクション
stage.addEventListener(MouseEvent.CLICK, xTrace);
function xTrace(eventObject:MouseEvent):void {
  var myTarget:DisplayObject = eventObject.target as DisplayObject;
  var myCurrentTarget:DisplayObject = eventObject.currentTarget as DisplayObject;
  trace(myTarget, myTarget.name, myCurrentTarget);
}

マウスとインタラクションをもたせるインスタンスは,入れ子の親子になっていたり,中に兄弟のインスタンスが並べられていることはむしろ多いだろう。そのような場合のマウスイベントの扱いについて,あともう1回だけ解説に充てたい。

※2
イベントの発生が親インスタンスに伝わるかどうかは,イベントによって違う。したがって,イベントごとに確かめる必要がある。

今回解説した次のサンプルファイルがダウンロードできます。

著者プロフィール

野中文雄(のなかふみお)

ソフトウェアトレーナー,テクニカルライター,オーサリングエンジニア。上智大学法学部卒,慶応義塾大学大学院経営管理研究科修士課程修了(MBA)。独立系パソコン販売会社で,総務・人事,企画,外資系企業担当営業などに携わる。その後,マルチメディアコンテンツ制作会社に転職。ソフトウェアトレーニング,コンテンツ制作などの業務を担当する。2001年11月に独立。Web制作者に向けた情報発信プロジェクトF-siteにも参加する。株式会社ロクナナ取締役(非常勤)。

URLhttp://www.FumioNonaka.com/

著書