- ベストアンサー
複数のキャラにonRollOverで吹き出しをださせる
- MX2004の初心者の方が、複数のキャラクターにマウスオーバーした際に吹き出しを表示する方法について質問されています。
- 質問者はchara1_mcとchara2_mcという二つのキャラクターが隣り合っており、それぞれに対して0nRollOverした際にマスクでfukidasi_mcを出すスクリプトを作成しました。
- しかし、chara1からchara2に素早く移動した場合、chara1の吹き出しの戻りが途中で止まり、chara2の吹き出しも表示されません。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
#1 & #2 です。 #2を回答した後, 存在意味の不明な if文 について考えてみました。 そして,この不可解な if文は, 「enterFrame で徐々に上げたり下げたりするためにあるのではいの?」 という結論(推論)に至りました。 #2に回答したムービーの構造であるとして, なるべく元のままのスクリプトを残す形で考えてみました。 スクリプトを次のようにすれば,望み通りの動きをしませんか?↓ ------------------------------------------- // 吹き出し fukidasi1 の上への最高点を fukidasi1Max に代入 var fukidasi1Max = fukidasi1._y-80; // 吹き出し fukidasi1 の最初の位置を fukidasi1Min に代入 var fukidasi1Min = fukidasi1._y; // // 吹き出し fukidasi2 の上への最高点を fukidasi2Max に代入 var fukidasi2Max = fukidasi2._y-80; // 吹き出し fukidasi2 の最初の位置を fukidasi2Min に代入 var fukidasi2Min = fukidasi2._y; // // chara1 にロールオーバーしたとき chara1.onRollOver = function() { this.onEnterFrame = function() { fukidasi1._y -= 5; if (fukidasi1._y<=fukidasi1Max) { fukidasi1._y = fukidasi1Max; } }; }; // chara1 からロールアウトしたとき chara1.onRollOut = function() { this.onEnterFrame = function() { fukidasi1._y += 5; if (fukidasi1._y>=fukidasi1Min) { fukidasi1._y = fukidasi1Min; } }; }; // chara2 にロールオーバーしたとき chara2.onRollOver = function() { this.onEnterFrame = function() { fukidasi2._y -= 5; if (fukidasi2._y<=fukidasi2Max) { fukidasi2._y = fukidasi2Max; } }; }; // chara2 からロールアウトしたとき chara2.onRollOut = function() { this.onEnterFrame = function() { fukidasi2._y += 5; if (fukidasi2._y>=fukidasi2Min) { fukidasi2._y = fukidasi2Min; } }; }; ------------------------------------------- 上のスクリプトで良ければ,以下は私の推測です。 ロールアウトしたときに,それまでの動きが止まるのは, #2でも少し書きましたが,後に定義される関数の方が優先されるためだと思います。 _root.onEnterFrame 1本で, 吹き出しを上下させようとするからそうなるのではないかと思います。 上の onEnterFrame は, chara1.onEnterFrame と chara2.onEnterFrame に分散させています。 だから,他のものに動きを阻止されることはありません。 もちろん, _root.onEnterFrame 1本でもできますよ。 でもそれをするには,スクリプトの大幅変更になってしまいます。 onEnterFrame の奪い合いが怪しいのだと思います。 結論は #1,#2 を通して同じで, > 専門学校の先生に訊くと、それはonRollOverの特徴だ これが大嘘です。 (もしくは説明不足。)
その他の回答 (2)
#1です。 > chara1,2_mcとfukidasi1,2_mcはすべてステージ上に配置しています。 これは階層構造は入れ子状態になっていなくて, 4つのムービークリップはフラットに _root の直下に置いてあるということですよね。 また, 説明のンスタンス名とスクリプトに書かれているインスタンス名とがずれています。 スクリプトの方を優先させたとして,階層構造は次のようになっていると解釈します。 _root ├chara1 ├fukidasi1 ├chara2 └fukidasi2 レイヤー構造は次のようになっているとします。 ------------------------------ ActionScript レイヤー fukidasi1 の マスクレイヤー fukidasi1 レイヤー fukidasi2 の マスクレイヤー fukidasi2 レイヤー chara1 & chara2 レイヤー ------------------------------ しかし, 書かれていらっしゃるスクリプトは, chara1.onRollOver = function(){} が2つも書いてありますよ。 2つも同じ function を書くと, 下(後)に書いた方が優先されて,上(先)に書いた方は無効になります。 あと, 存在理由の不明な if 文 がありますが, その存在理由が不明な点は除くとして, if文の不等号の向きが逆ですよ。 次のようにすれば, 何事もなく無事に動作します。 --------------------------------------- / 吹き出し fukidasi1 の上への最高点を fukidasi1Max に代入 var fukidasi1Max = fukidasi1._y-80; // 吹き出し fukidasi1 の最初の位置を fukidasi1Min に代入 var fukidasi1Min = fukidasi1._y; // // 吹き出し fukidasi1 の上への最高点を fukidasi2Max に代入 var fukidasi2Max = fukidasi2._y-80; // 吹き出し fukidasi1 の最初の位置を fukidasi2Min に代入 var fukidasi2Min = fukidasi2._y; // // chara1 にロールオーバーしたとき chara1.onRollOver = function() { fukidasi1._y -= 5; if (fukidasi1._y>=fukidasi1Max) { fukidasi1._y = _root.fukidasi1Max; } }; // chara1 からロールアウトしたとき chara1.onRollOut = function() { fukidasi1._y += 5; if (fukidasi1._y<=fukidasi1Min) { fukidasi1._y = _root.fukidasi1Min; } }; // chara2 にロールオーバーしたとき chara2.onRollOver = function() { fukidasi2._y -= 5; if (fukidasi2._y>=fukidasi2Max) { fukidasi2._y = fukidasi2Max; } }; // chara2 からロールアウトしたとき chara2.onRollOut = function() { fukidasi2._y += 5; if (fukidasi2._y<=fukidasi2Min) { fukidasi2._y = fukidasi2Min; } }; --------------------------------------- しかし, if文は理解不能です。何を判定させているのでしょうか? --------------------------- fukidasi1._y -= 5; if (fukidasi1._y>=fukidasi1Max) { fukidasi1._y = _root.fukidasi1Max; } --------------------------- ↓ 変更 ↓ --------------------------- fukidasi1._y = _root.fukidasi1Max; --------------------------- こうすれば済むことですが。 とにかく,#1にも書きましたが結論は同じです。 onRollOut とか onRollOver に問題は無いはずです。 それ以外の箇所を疑ってください。 (#1ではスバリと書くことを差し控えましたが,専門学校の先生 が怪しいということです。)
よくわかりません。 とうかそう言う現象には全くなりません。 また, Flash のエリア外にマウスを素早く出した場合, マウスが Flash から離れたことを検知できないという問題はよく聞きますが, 他のMCや他のボタンに即 on (rollOver) したからといって, その前のMCやボタンの on (rollOut) が無効になるという話はいまのところ聞いたことがありません。 ためしに次のような階層のMCを作成しました。 _root ├chara1_mc │ └fukidasi1_mc └chara2_mc └fukidasi1_mc chara1_mc と chara2_mc は長方形の塗りを MC にしたものです。 chara1_mc と chara2_mc の間にはわざと隙間を作っていません。 chara1_mc chara2_mc □□□□□■■■■■ □□□□□■■■■■ □□□□□■■■■■ □□□□□■■■■■ □□□□□■■■■■ chara1_mc と chara2_mc それぞれのMCの中には, fukidasi1_mc を置いてみました。 chara1_mc chara2_mc 回回回□□■■回回回 回回回□□■■回回回←吹き出し 回回回□□■■回回回 fukidasi1_mc □□□□□■■■■■ □□□□□■■■■■ fukidasi1_mc の中身は 2フレーム でできていて, フレーム1 は空にして,フレーム2 に吹き出しを入れ, フレーム1 で stop() させてあります。 ---fukidasi1_mc のタイムライン------- レイヤー 筆・・・|○ []| ←フレーム1 に stop(); レイヤー 筆・・・|○|●| ←フレーム2 に吹き出し -------------------------------- そして, chara1_mc にも chara2_mc にも, 同じスクリプトで次のように書きました。 ---------------------------------- on (rollOver) { this.fukidasi1_mc.gotoAndStop(2); } on (rollOut) { this.fukidasi1_mc.gotoAndStop(1); } ---------------------------------- どんなに素早くマウスを動かして, chara1_mc → chara2_mc chara1_mc ← chara2_mc しても,両者の on (rollOut) は有効に働きます。 つまり, chara1_mc → chara2_mc とマウスを移動させても, chara1_mc → 別のところ とマウスを移動させても, chara1_mc の on (rollOut) は有効に働いて, その中の fukidasi1_mc は見えなくなるということです。 on (rollOut) に問題があるのではなくて, 何か別のところに吹き出しを止める原因があるのではないでしょうか。 例えば, 素早くロールアウトするときに,実はクリックしてしまっているとか…。 (そういう癖があるとか,何かそうなる原因があるとかです。) その場合は,次のように対処する方法もあります。 -------------------------------------- on (rollOver) { this.fukidasi1_mc.gotoAndStop(2); } on (rollOut, dragOut) { this.fukidasi1_mc.gotoAndStop(1); } -------------------------------------- 上の2例のスクリプトは, ムービークリップ自体に書いていますが, フレームに次のように書いても同じ事です。 -------------------------------------- for (i=1; i<=2; i++) { _root["chara"+i+"_mc"].onRollOver = function() { this.fukidasi1_mc.gotoAndStop(2); }; _root["chara"+i+"_mc"].onRollOut = function() { this.fukidasi1_mc.gotoAndStop(1); }; _root["chara"+i+"_mc"].onDragOut = _root.chara1_mc.onRollOut; } --------------------------------------
お礼
回答ありがとうございます、sassakunさん。 私の説明が足りなかったかもしれません。
補足
sassakunさんの書いてくれた図を利用して説明いたいと思います。 chara1,2_mcとfukidasi1,2_mcはすべてステージ上に配置しています。 fukidasi1,2_mcそれぞれは、chara1,2_mcそれぞれと同じ位置に配置しています。 fukidasi1,2_mcそれぞれを、マスクで隠しています。下記の○はマスク対象範囲 ○○○ ○○○ ○○○ ○○○ ○○○ ○○○ 回回回□□■■回回回 吹き出し→回回回□□■■回回回←吹き出し fukidasi1_mc回回回□□■■回回回 fukidasi2_mc □□□□□■■■■■ □□□□□■■■■■ chara1_mc chara2_mc そして、 var fukidasi1Max = fukidasi1._y -80; //吹き出しの上への最高点 var fukidasi1Min = fukidasi1._y; //吹き出しの最初の位置(下へ戻す位置) chara1.onRollOver = function(){ fukidasi1._y -= 5; if( fukidasi1._y <= fukidasi1Max ){ fukidasi1._y = fukidasi1Max; } } chara1.onRollOver = function(){ fukidasi1._y += 5; if( fukidasi1._y >= fukidasi1Min ){ fukidasi1._y = fukidasi1Min; } } chara2も同様です。 ロジックは間違ってないと思っていますが。いかがでしょうか?
お礼
はやい回答に感謝します。 sassakunさんの解釈は正しいです。 sassakunさんの方法でうまくいきました。勉強になります。初心者なのであまり深く考えず覚えていきたいと思います。 ありがとうございました。 実は、今頃、教室でやったことを思い出したんですけど、this.onEnterFrameを使わず、オリジナル関数tobidasi();とhikkomi();をそれぞれonRollOverとonRollOutの中に入れていました。 chara1.onRollOver = function() { tobidasi(); } function tobidasi(){ fukidasi1._y -= 5; if (fukidasi1._y<=fukidasi1Max) { fukidasi1._y = fukidasi1Max; } } chara1.onRollOut = function() { hikkomi(); } function hikkomi(){ fukidasi1._y += 5; if (fukidasi1._y>=fukidasi1Min) { fukidasi1._y = fukidasi1Min; } } こんな具合にです。手間を取らせてすみませんでした。(汗)