電子書籍の厳選無料作品が豊富!

以下のムービーを作ったのですが動作がおかしいです。
----------------ステージ-------------
| [ボタン]  [photo(mc_0とmc_1)] |
-------------------------------------
【ムービーの説明】
load時:photo(mc)がmcPos[-203]の位置に移動
enterframe:ボタンにmouseoverでそれぞれの座標に移動
※photoは同じものを二枚重ねて、それぞれにmc_0とmc_1とインスタンス名をつけて、異なるスピードで移動。「//」で斜めにマスクを作っているので、ひとつの写真が斜めにずれながら移動しているように見える
【おかしな動作】
loading動作してない状態(FlashMXで単にCtrl+Enter)した状態だと再生時に「mcPos」の「-203」にphotoは移動するのですが、loadingを動作させると再生時にphotoが移動しない。ボタンにonRollOverしたときには、ちゃんとそれぞれの座標に移動します。ただ再生時に「mcPos」の「-203」に移動しない。
/---rootの1フレーム目(ローディング)---/
this.stop();
defWidth = bar._width;
if (getBytesLoaded() == getBytesTotal()) {gotoAndStop("start");}
this.onEnterFrame = function(){
per = Math.floor(getBytesLoaded()/getBytesTotal()*100);
loading = "Now Loading..."+per+"%";
bar._width = defWidth*(per/100);
};
/---rootの2フレーム目---/
this.stop();
mc_0.setMask(mask_0);
mc_1.setMask(mask_1);
mcPos=new Array();
mcPos=[-203, -589, -1361, 183, -975, -1747];
this.onLoad=function(){a=0;};
this.onEnterFrame = function(){
mc_0._x += (mcPos[a]-mc_0._x)/1.4;
mc_1._x += (mcPos[a]-mc_1._x)/2;
};
/---rootの2フレーム目(インターフェイス)---/
ボタン(mc)の編集画面
on(rollOver){_root.a = 0;gotoAndStop("top");}
on(rollOut){gotoAndStop("out");}
on (release, releaseOutside){getURL("index.html");}

A 回答 (1件)

おそらく、変数 a を _root の load イベントを使って初期化していることが原因だと思います。


確かに _root もムービークリップですから、メインのタイムラインで this.onLoad = function()・・・と書いても文法上は間違いではありませんが、_root での load イベントは意外にアテにならない(ダウンロード時には onLoad で定義した関数が呼び出されない)ものなので、変数の初期化に使うのはオススメしません。


フレーム2では、 onEnterFrame イベントを使って

 mc_0._x += (mcPos[a]-mc_0._x)/1.4;
 mc_1._x += (mcPos[a]-mc_1._x)/2;

と、a を使って配列変数を参照する処理を定義していらっしゃるようですが。
参照しようとした変数が定義されていない場合は、undefined という値が返されます。
undefined は Flash の内部では0が割り当てられており、Flash Player 6 までは未定義の変数の値は0として処理されていました。
しかし、Flash Player 7(作成ツールは Flash MX 2004 )では undefined の解釈が変更され、0とは見なされなくなりました。変数に明示的に初期値を入れない限り、変数を使った演算は正常に行われません。

つまり、

 this.onLoad=function(){a=0;};

で定義した関数が呼び出されていないと、変数 a は初期化されず、未定義 = undefined となります。
a を参照して配列変数から値を取ってこようとしても、a という変数は存在しないことになっているので、値の取得に失敗してしまうというわけです。


ムービー再生中、本当に最初の1度だけ変数を初期化したいのであれば、この undefined を利用して

 if( a == undefined )
 {
  a = 0;
 }

(↑各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください)

このようなスクリプトで初期化できます。
ご質問文の例ですと、フレーム2で、this.onLoad =・・・の代わりに使ってみてください。
後で gotoAndPlay などでフレーム2が再度再生されることがあっても、この時には変数 a は既に存在していて undefined ではありませんから、if 文の条件が不成立になり、a = 0; は実行されません。

フレーム2が2度と再生されないか、あるいは、フレーム2に戻るたびに0になっても問題がないのであれば、undefined かどうかで判断しなくても、単に a = 0; として初期化しても構いません。


ちなみに、未定義の変数を算術演算に利用すると、似たような不具合が起こることがあります。
未定義の変数で、例えば a++; といった計算をすると、結果は NaN (数値ではないもの)という値になります。
算術演算に利用する場合は特に、変数の初期化は大切です。フレームアクションなどの確実に初期化できる方法で、明示的に初期値を入れてから利用するようにしましょう。

変数を利用した演算で、全く動作しないといった不可解なことが起きたら、変数や演算の結果が undefined か NaN になっていないかどうかを疑ってみてください。
変数の値は、trace アクションを使って

 trace( a );

として「出力」パネルに表示するか、デバッガという機能を使って確認できます。
    • good
    • 0
この回答へのお礼

ありがとうございます。
ばっちり動作しましたっ!!
いや~、ちょっと本を見て勉強したぐらいだとなかなか上手くいかないっすね~~!!
もっともっと勉強せねばかな。

お礼日時:2005/07/18 21:17

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