- ベストアンサー
Flashのフラッシュ宝箱のスライド式メニューとドラッグ&ドロップでグリッドに吸着がうまく動作しない問題について
- Flash宝箱のスライド式メニューとドラッグ&ドロップでグリッドに吸着がうまく動作しない問題について教えてください。
- 具体的には、スライド式メニューと『glid.fla』を組み合わせたものを作りたいのですが、『glid.fla』が反応せずに正常に動作しません。
- 解決策を考える上で、パスの設定やonClipEvent(load)の重複などに問題があるのかもしれません。質問者はFlash経験が浅く、MAXを久しぶりに使用しているそうです。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
幼稚なことなどではありません。難しい問題です ^^; まず、簡単な実験をしてみますと。 赤の丸を描いてボタンシンボルに変換し、「オーバー」のフレームでは、これを青に塗り替えます。 何の変哲もないボタンですから、カーソルを合わせると、赤い丸が青に変わります。 次に、このボタンのインスタンスを更にムービークリップに変換し、ボタンをムービークリップの入れ子にします。 この状態ではボタンは反応しますが、ムービークリップに on(press) アクションを設定すると、ボタンは反応しなくなります。 このボタンはムービークリップの一部でもあるので、親のムービークリップが press や release などのボタンとしての機能を利用している時は、ボタンの上でマウスを操作しても、Flash の内部では親のムービークリップで起きたイベントと見なされます。 ボタンではイベントそのものが起きていないことになりますから、ボタンは全く反応しなくなるというわけです。 ボタンとムービークリップを例にしましたが、ムービークリップ同士でも同じことです。 ムービークリップ CONTENT2 に img を作り、これに glid.swf を読み込むと、glid.swf が持っていたムービークリップやボタンは、全て img の子になります。 img は CONTENT2 の子です。 CONTENT2 に on(press) などのボタンイベントを利用するアクションが書かれていると、CONTENT2 の子になっているムービークリップやボタンではボタンイベントは検出されません。 ------------------------------------------------------ Flash 側からイベントが発行されない以上は、親がボタンイベントを使っていても、子の階層で擬似的にイベントを検出できる仕組みを考えなければなりません。 press や release イベントが発生した時にどんなことが起きているかを考えると、これらに代わる処理は何となく浮かんでくると思います。 press は”ムービークリップやボタンがクリックされた時”に起こるものです。 (この先は文章が複雑になるなので、ムービークリップだけで考えます) つまり、 ・マウスのボタンが押される ・ムービークリップにカーソルが重なっている この2点が条件です。 では、release はどうでしょう。release イベントは、必ず press イベントが起きた後に発生します。 従って ・マウスのボタンが押されて離された時に発生する ・ムービークリップにカーソルが重なっている となります。 マウスボタンに関しては、ムービークリップの mouseDown や mouseUp イベントで検出できます。 ただ、これらのイベントはムービークリップの上でなくても発生するので、別途、カーソルがムービークリップの上にあるかどうかを判断しなければなりません。 ムービークリップとカーソルが重なっているかどうかは、衝突判定をとる hitTest で何とかなりそうです。 擬似 onPress 処理をスクリプトにしますと、 (↓各行頭に全角のスペースが入っています。コピーする際はご注意ください) //擬似onPress処理 onClipEvent(mouseDown) { //カーソルと重なっていたら、pressイベント発生と見なす if( this.hitTest( _root._xmouse , _root._ymouse , true ) ) { /*ここにpressイベント発生時の処理を書く*/ } } こんな感じになります。 ところで、ドラッグは release の他に、releaseOutside イベントも利用することがあります。 releaseOutside とは、press と同様にムービークリップの上でマウスのボタンをクリックした後、ムービークリップ外でマウスのボタンが離された時に起こるイベントです。 release はカーソルとムービークリップが重なっていないと発生しませんが、releaseOutside ではカーソルが重なっていなくてもいいのですから、カーソルとの衝突判定をとる必要はありません。 つまり、このどちらかのイベントが起きた時にドラッグを終了するのであれば、 ・press イベントが発生した後(ドラッグ中)である ・マウスのボタンが離された この2点の条件が揃った時に、ドラッグをやめればいいことになります。 そこで、変数(フラグといいます)を1つ用意し、ドラッグを開始した時に、ドラッグ中であるという記録を残します。 ドラッグ中かどうかだけ分かればいいので、値は true と false で充分です。 この変数を見ると、ドラッグ中だったかどうかが分かります。mouseUp イベントが起きた時は、ドラッグ中の場合だけ、ドラッグをやめればいいわけです。 まとめますと、glid.swf のムービークリップに書くスクリプトは、大体、次のようになります。 slide.swf に読み込んだ時に on(press) や on(relase,releaseOutside) は意味をなくしてしまいますので、コメントにしておくといいでしょう。 ドラッグ中かどうかの情報を保持する変数は drag_flg としています。 onClipeEvent(load) の中で、 //ドラッグフラグ //ドラッグ中true、それ以外はfalse drag_flg = false; というように初期化をしてください。 //擬似onPress処理 onClipEvent(mouseDown) { //カーソルと重なっていたら、pressイベント発生と見なす if( this.hitTest( _root._xmouse , _root._ymouse , true ) ) { //ドラッグ開始 this.startDrag(); //ドラッグ中であることを記録 this.drag_flg = true; } } //擬似onRelease・onReleaseOutside処理 onClipEvent(mouseUp) { //ドラッグ中だった時のみ、release・releaseOutsideイベント時と同じ処理を実行 if( this.drag_flg ) { //ドラッグ終了 this.stopDrag(); //ドラッグフラグをクリア this.drag_flg = false; /*ここに、ドラッグ終了時に実行する処理を書く*/ } } glid.swf のムービークリップをドラッグはできますが、手のひらカーソルには変わりません。 手のひらカーソルに変わるのはボタンイベントが起きた時だけなので、仕方ありませんね。 どうしてもというのなら、カスタムカーソルのムービークリップを用意し、glid.swf のムービークリップを動かしている時だけ、カーソルを消してカスタムカーソルを表示するといった方法になるかと思います。 長くなってすみませんでした。 不明な点がありましたら、補足してください。
お礼
すごい!!!!!!!!!!!!!!!!!!!!! ここまで解説していただけると お礼だけでいいのかな?と思ってしまいます。 これまで疑問に思ってた内容も随分クリアになりました。 本当にありがとうございます。 すごすぎる。