- 2009年10月25日 01:10
- ActionScript 3.0 | Flash
そもそもこいつが無いと成り立たない!というくらい
Flash制作する際に最も重要といっても過言ではないもの
それは MouseEvent ではないでしょうか。
なにかとお世話になる MouseEvent ですが
意外と細かい扱い方を知っている人は少なかったりします。
ですので今回は MouseEvent の伝播の仕組みについてです。
ちなみに、capture bubbling に関しての話は
ひとつの記事に収めるには複雑になりすぎるので今回は触れません。
Flash制作する際に最も重要といっても過言ではないもの
それは MouseEvent ではないでしょうか。
なにかとお世話になる MouseEvent ですが
意外と細かい扱い方を知っている人は少なかったりします。
ですので今回は MouseEvent の伝播の仕組みについてです。
ちなみに、capture bubbling に関しての話は
ひとつの記事に収めるには複雑になりすぎるので今回は触れません。
◆ MouseEvent の伝わり方
例えば、以下のサンプルのように、ステージに配置された要素をクリックすると
ランダムで位置が変わるとしましょう。
構造的にはこう

例えば、B をクリックした場合
内部では以下の経路でイベントが通知されます

実際はもう少し複雑(capture とか bubbling とか)なのですが
端的に言うとこういったイメージでイベントが伝播します。
ちなみに、A と B が重なった場合には B をクリックする事は基本的に出来ません。
重なりが上になっているものがクリックできる というのは、感覚的にも想像しやすい挙動だと思います。
ちなみに、コレを逆手に取った Tips として
透明な塗りの要素をステージの最上位に addChild してしまう事で
あらゆる要素をクリックできなくする事が出来ます。
※ わかりやすくするため網掛けにしてあります
これは、ステージの直下に塗り( サンプルでは sheet というMovieClip )を置く事で
イベントの伝播が、以下のようになるからです。

まあ、言わずもがなといったところでしょう。
最上部に塗りがあって、下に到達する事をブロックしているため
塗り以下のレイヤにイベントが行かないというわけです。
これは結構使われている手法ですし
直感的に理解しやすい(重なりが上のものにイベントが行く)ものですので
そんな Tips は知ってるよ、という方も多いでしょう。
まあ、ここまではウォーミングアップです。
次はこのイベントの伝播を制御してみようと思います。
◆ MouseEvent の伝播の制御方法
さて、先ずは以下のFlashを触ってみてください。
さっきと同じに見えますが、ちょっとした違いがあります。
触ってもらえばわかっていただけるかと思いますが
このFlashは上に半透明の要素を被せているのに下の要素がクリックできます。
意外とこれのやり方を知らない人は多いんじゃないでしょうか。
イベントの伝播と制御方法を理解すると
こんなFlashを作る事が可能になります。
伝播の経路を制御する方法として
Flashには mouseEnabled と mouseChildren
という2つのプロパティが存在します。
◆ mouseEnabled : MouseEventを受け取るかの設定
mouseEnabled は Sprite や MovieClip が、MouseEvent の通知を
受けるか否かを設定できます。 false の場合は通知をうけません。
var spriteA:Sprite, spriteB:Sprite, spriteC:Sprite; spriteA.addChild( spriteB ); spriteB.addCHild( spriteC ); // MouseEvent の通知を受けない. spriteB.mouseEnabled = false;
イメージとしては以下のような状態です。

このプロパティを false にしても、MouseEventを受け取らないだけであって
自分の子に対してはイベントが伝播する事に注意してください。
◆ mouseChildren : MouseEventを子に通知するかの設定
mouseChildren は Sprite や MovieClip が、MouseEvent の通知を
自分に addChild されている要素に通知するかを設定できます。
false の場合は、子要素に通知を行いません。もちろん、孫以下にも通知されません。
var spriteA:Sprite, spriteB:Sprite, spriteC:Sprite; spriteA.addChild( spriteB ); spriteB.addCHild( spriteC ); // MouseEvent を子に通知しない. spriteA.mouseChildren = false;
イメージとしては以下のような状態です。

このプロパティをfalse にしても、自分自身はイベントを
受け取るという事に注意してください。
◆ 実際に制御してみる
さて、この2つをうまく使ってあげると
前述したようなマウスイベントが貫通するFlashを作ることが出来ます。
では具体的にどうやるのかというと
以下のような構成にすることで実現しています。

これでイベントが貫通します。
layer というMovieClip があり、その子要素として
sheet という半透明の塗りの MovieClip がぶら下がっています。
( 要素の名称などに意味は無いので自由につけてください )
しかし layer は mouseEnabled, mouseChildren 共に false であるため
全くイベントを受け取れません。そのため、重ね順では下にあるはずの
mcA, B, C が次の通知対象となり、マウスイベントが伝播するというわけです。
まあ、視覚的には貫通したように見えているだけで
正確には、イベントの伝播経路が変わったというべきでしょうか。

また、今回は mouseEnabled, mouseChildren 両方を説明する意味もかねて
あえて子階層を持つ要素(layer)を MouseEvent が貫通するように作っています。
もし、layer が子要素を持っていないような場合においては
layer.mouseEnabled = false; のみで貫通します。
ただ、上記のような構成にしておくと、手前に置くけど MouseEvent とりたくない
という要素を、ひたすら layer に突っ込めば良くなるので、実装上は便利です。
これが貫通Flashのトリックです。
これの何が便利なのかって話がありますが、例えば
サイト全体に網掛けするとか、光で白く薄くなっている部分を作りたいとか
あとは、静物の後ろに隠れているキャラクタをクリックさせたいとか
表現の都合上手前に表示したいけど
MouseEventを奪ってほしくないものに絶大な効果を発揮します。
地味ーーーに使いどころがあったります。
◆ まとめ
あんまりうまく説明できていなくて申し訳ないのですが
MouseEvent の伝播の仕組み、知っておくと何かと便利でっせ。
というお話です。
今回はこの辺で。 なにか質問等がありましたら、メッセージでも twitter でもお気軽にどうぞ。
- Newer: AS3.0 EnterFrameをまとめると速いよの話のやつ
- Older: Flash制作に欠かせない3つのツール・flair4jp編