あなたの習慣について教えてください!!

うまくいかない原因がわからず困っています。
画面上の複数のmcに同じイベントを記述しました。
内容はシンプルで、「mc01にマウスがのったらフレームf01に移動する、
マウスが離れたらフレームstartに戻る」というものです。
mc02はf02へ、mc03はf03へ移動というふうにします。

これをmc01からmc07まで順番に書いていったところ
mc07は反応するのですが、あとの6つが反応しません。
mc07の記述を消すとmc06が反応するようになり、
どうやら一番最後に記述している部分しか反応しないようです。

これ↓がそれぞれのmcに書いてるASです。
----------------------------------------------------------
onClipEvent (enterFrame) {
if (_root.mc01.hitTest(_root._xmouse,_root._ymouse,1)) {
_root.gotoAndPlay("f01");
} else {
_root.gotoAndPlay("start");
}
}
----------------------------------------------------------
ちなみにFlash8使用、プレイヤー8でパブリッシュしてます。
どうぞよろしくお願いします。

A 回答 (2件)

どこから説明すれば良いか困りますね。


長くなりますが,広く浅く説明します。


onClipEvent (enterFrame) {○○}
は1フレーム進む時間ごとに毎回 ○○ の部分が実行されます。
そこは宜しいですよね?

この onClipEvent(enterFrame){○○} を各ムービークリップに書くということは,
各ムービークリップの onClipEvent(enterFrame){○○} の○○が
1フレーム進む時間ごとに毎回順次実行されるということです。

この各ムービークリップの
onClipEvent (enterFrame) {○○} の実行順序ですが,
これは [パブリッシュ設定] の [Flash]タブ にある,

 ダウンロードの順序(L):[下から上へ  v]

となっているところで決まります。

[下から上へ] を [上から下へ] などに変えると,
逆に mc01 のみが反応するように変わると思います。
※デフォルトは [下から上へ] です。
  通常それで問題はありません。
  またそこを変えても何の解決にもならないので
  実験してみるだけにしておいて,
  本番は変えない方が良いです。

順序の規則(法則)については詳しく書きませんし複雑です。
とにかく,
 各ムービークリップの onClipEvent(enterFrame){○○} の○○が
 1フレーム進む時間ごとに毎回,不明な順序で実行される。
ということだけはちゃんと認識しておく必要があります。


ご質問のような現象が起こるのは,

 mc01 の onClipEvent(enterFrame){○○} が実行
 mc02 の onClipEvent(enterFrame){○○} が実行
 mc03 の onClipEvent(enterFrame){○○} が実行
      …略…
 mc07 の onClipEvent(enterFrame){○○} が実行

という順で実行されるので起こる現象です。

たとえば,
「mc01」にだけ マウスが乗っていたとします。

 mc01 の onClipEvent(enterFrame){○○} が実行

ここ↑でフレーム「f01」に進もうとします。
これがやりたいことですよね。
しかし次の

 mc02 の onClipEvent(enterFrame){○○} が実行

が実行されたときには,
マウスは「mc02」には乗っていないのですから,
このスクリプトによって フレーム「start」 に進もうとします。
次の

 mc03 の onClipEvent(enterFrame){○○} が実行

によっても フレーム「start」 に進もうとします。
最後の

 mc07 の onClipEvent(enterFrame){○○} が実行

によっても フレーム「start」に進もうとします。

旗上げゲームで言うと
  「赤上げて,赤上げないで,赤上げない。」
   →赤が下がっているのが正解!
と同じ状態です。

したがって,結局最後に実行される
mc07 の onClipEvent (enterFrame) {○○} が最優先されて,
「mc01」にだけマウスが乗っていた場合,
フレーム「start」に進みます。

以上がそうなる理由です。



=== === === === === ===

解決策ですが。

そもそも Flash 5 時代にしか使われなかったような,
onClipEvent(enterFrame){○○} を使うところに
問題を生じやすくさせる原因があると思います。

普通 onClipEvent (enterFrame) {○○} などは
それ相応の理由がない限り使いません。

※仮に Flash 5 であっても
  指令塔のようなムービークリップを1つ作成して
  その 1ムービークリップ の onClipEvent(enterFrame){○○} だけによって
  全体を管理するというのが普通のやり方です。



ご質問内容にあるようなことをする場合で,
なおかつ,スクリプト内容も変えない場合は次のようにします。

まず,
「mc01」~「mc07」 自体に書いた onClipEvent(enterFrame){○○} を全て削除します。

そして _root のフレーム1などに次のように書きます。

---------------------------------------------------
_root.onEnterFrame = function() {
if (_root.mc01.hitTest(_root._xmouse, _root._ymouse, 1)) {
_root.gotoAndPlay("f01");
} else if (_root.mc02.hitTest(_root._xmouse, _root._ymouse, 1)) {
_root.gotoAndPlay("f02");
} else if (_root.mc03.hitTest(_root._xmouse, _root._ymouse, 1)) {
_root.gotoAndPlay("f03");
} else if (_root.mc04.hitTest(_root._xmouse, _root._ymouse, 1)) {
_root.gotoAndPlay("f04");
} else if (_root.mc05.hitTest(_root._xmouse, _root._ymouse, 1)) {
_root.gotoAndPlay("f05");
} else if (_root.mc06.hitTest(_root._xmouse, _root._ymouse, 1)) {
_root.gotoAndPlay("f06");
} else if (_root.mc07.hitTest(_root._xmouse, _root._ymouse, 1)) {
_root.gotoAndPlay("f07");
} else {
_root.gotoAndPlay("start");
}
};
---------------------------------------------------

これで,
最後の「mc07」のスクリプトだけが動作するということはなくなります。



=== ===

ただしー! ですね。

最初に書きましたが,
onClipEvent (enterFrame) {○○} は,
1フレーム進む時間ごとに毎回 ○○ の部分が実行されます。
また上に書いた
○○.onEnterFrame = function() {○○} も
1フレーム進む時間ごとに毎回 ○○ の部分が実行されます。
つまりどっちにしても,
1フレーム進む時間ごとに毎回 ○○ の部分が実行されることには変わりがありません。


たとえば 「どのmcにもマウスが乗っていないとき」。
_root.gotoAndPlay("start");
これが1フレーム進む時間ごとに毎回実行されます。

つまり,1フレーム進む時間ごとに毎回フレーム「start」に行き続けます。

1フレーム進む時間ごとに毎回フレーム「start」に行き続けるということは
ずっと フレーム「start」 で止まりっぱなしになります。
ひとつも _root.gotoAndPlay("start"); の play は実行されないということです。


1フレーム進む時間ごとに毎回 フレーム「××」 に行きつづけさせないようにするのは,
何かフラグとなるような変数を1つ作って,
そのフラグを切り替えて,そのフラグによって動作を変えるようにするのも1つの方法です。

上のスクリプトを全て消して,
次のスクリプトに書き替えです。

---------------------------------------------------
var flag:Boolean = false;

_root.onEnterFrame = function():Void {
if (_root.mc01.hitTest(_root._xmouse, _root._ymouse, 1)) {
if (!flag) {
_root.gotoAndPlay("f01");
flag = true;
}
} else if (_root.mc02.hitTest(_root._xmouse, _root._ymouse, 1)) {
if (!flag) {
_root.gotoAndPlay("f02");
flag = true;
}
} else if (_root.mc03.hitTest(_root._xmouse, _root._ymouse, 1)) {
if (!flag) {
_root.gotoAndPlay("f03");
flag = true;
}
} else if (_root.mc04.hitTest(_root._xmouse, _root._ymouse, 1)) {
if (!flag) {
_root.gotoAndPlay("f04");
flag = true;
}
} else if (_root.mc05.hitTest(_root._xmouse, _root._ymouse, 1)) {
if (!flag) {
_root.gotoAndPlay("f05");
flag = true;
}
} else if (_root.mc06.hitTest(_root._xmouse, _root._ymouse, 1)) {
if (!flag) {
_root.gotoAndPlay("f06");
flag = true;
}
} else if (_root.mc07.hitTest(_root._xmouse, _root._ymouse, 1)) {
if (!flag) {
_root.gotoAndPlay("f07");
flag = true;
}
} else if (flag) {
_root.gotoAndPlay("start");
flag = false;
}
};
---------------------------------------------------

これ↑は長いので,
次↓のように for文を用いて短くしても良いかもしれません。

---------------------------------------------------
var ON_flag:Boolean = false;
var Hit_flag:Boolean;
var i:Number;

_root.onEnterFrame = function():Void {
Hit_flag = false;
for (i=1; i<=7; i++) {
if (_root["mc0"+i].hitTest(_root._xmouse, _root._ymouse, 1)) {
if (!ON_flag) {
_root.gotoAndPlay("f0"+i);
ON_flag = true;
}
Hit_flag = true;
break;
}
}
if (!Hit_flag && ON_flag) {
_root.gotoAndPlay("start");
ON_flag = false;
}
};
---------------------------------------------------



長くなりましたが,ポイントを要約すると次の2つなります。

◎「複数のインスタンスにスクリプトを書くと実行順序の把握が困難になる」
  →実行順序の把握をしようとするのではなくスクリプトを1つにまとめる
  ※スクリプトを1つにまとめると実行順序を気にしなくて良い上
    見通しが良くなり全体を管理しやすくなる (一石二鳥)

◎「enterFrame系スクリプトは1フレーム進む時間ごとに毎回実行される」
  → play() や gotoAndPlay() を使う場合は要注意
  ※ play() や gotoAndPlay() に限らず
    ずっと全く同じ命令を出しつづけることは避けるべき



~~~ ~~~ ~~~

あと,
どうしても hitTest を使わなければならないのでしょうか?

on(rollOver){○○} や onRollOver=function(){○○} ,
on(rollOut){○○} や onRollOut=function(){○○}
などを使えば
以上のようなことを一々考えずに簡単に済む話ですが。
「複数のmcに同じイベントを記述したら、1」の回答画像2
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。
大変参考になりました!!
実は最初、onRollOverを使って作ってみたのですがうまくいかず、
それでhitTestを使うことにしたのです。
が、たぶんそれも何か間違いがあったからだと思います。
とりあえず今回は教えていただいたスクリプトに書き換えて
なんとかまとめることができましたので、これでいこうと思います。
どうもありがとうございました。

お礼日時:2009/04/24 00:05

よくわかりませんが、何となくmc01~mc07までを同じ深度(レベル)で作成されている、もしくはattachMovieされてませんか?


そうであれば一番最後に作成またはアタッチされたムービーしか反応しないのは当然ですが・・・
    • good
    • 0
この回答へのお礼

基本的なことをきちんと理解していないのですが、
レベルのことはまったく頭になかったので
おっしゃるようなことが原因かもしれません。

mc01~mc07を1つずつ個別のレイヤーに配置していたのですが
全部を1つのレイヤーに入れたら動くようになりました。

ご回答どうもありがとうございました!

お礼日時:2009/04/22 18:42

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報