• ベストアンサー

for文について

以前もお聞きしたかも知れませんが、教えて頂きたく。 7フレームに以下のScriptを記述しています。 sheet.target.duplicateMovieClip(ctr,ctr) ; dummy_loader.loadClip(var_article[ctr-1]+".jpg",sheet[ctr]); gotoAndPlay("rtn") ; dummy_listener.onLoadError = function(target_mc:MovieClip, errorCode:String) { gotoAndstop("end") ; } dummy_listener.onLoadComplete = function(target_mc:MovieClip) { sheet[ctr]._name = ctr ; sheet[ctr]._x += (ctr - 1) * 90 ; var_ctr++ ; dummy_loader.unloadClip(var_article[ctr-1]+".jpg"); }; 「rtn」は6フレームのフレームラベル、「end」は8フレームのフレームラベルです。 var_articleと言う配列に入っている情報(Key項目)を元にJPEGを読込んでいます。 onLoadCompleteにてJPEGをセットして前のフレームに戻して配列にデータが入っている間6<->7フレームをグルグル回って処理しています。 正常に動いています。 これを、No.1005374の#3でDPEさんに指摘して頂いたようにfor文を使ってのループ処理に変えたいと思います。 for(i = 0; i <= ctr; i++) { sheet.target.duplicateMovieClip(ctr,ctr) ; dummy_loader.loadClip(var_article[i]+".jpg",sheet[i]); } これで、1件づつ読込んでonLoadCompleteにて複製したムービークリップに名前を付けて当該の座標に配置しようと試みました。が、結果はfor文が全て処理されてからonLoadCompleteの処理がなされてしまいます。 自らフレームを利用したループと、for文を利用したループと、何処が違うのでしょう?。 どうぞ宜しく御願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • DPE
  • ベストアンサー率85% (666/776)
回答No.2

http://okweb.jp/kotaeru.php3?q=1005374 の#3のお礼文を見た時、少々誤解なさっているのではと思ったのですが、案の定・・・ですね。 前回はファイルの名前や総数が分かりませんでしたので、1回読んでみてエラーがなければ、ファイルが存在するものと見なしてムービークリップに読み込む・・・という作業を繰り返すロジックでした。最終的な数が分からない以上、1つ1つ手探りで読んでいくしかないのは仕方ありません。 1度ファイルの存在を確認に行くということは、確認にかかる時間を考慮しなければなりませんでした。この待ち時間は、フレーム間をループしてフラグを監視するという方法で実現していたわけです。 MovieClipLoader を使ったところで、ファイルの数が分からなければ、とりあえず読み込みを始めてみて、onLoadStart イベントが発生すればファイルがあるものと見なし、次のファイルを探しに行くという、フレーム間をループしてフラグを確認しながら1つずつ順に読み込みの指令を出さなければならないロジックは同じです。 今回はファイル名を配列で持っており、読み込むファイル名や数が最初から判明しています。for 文を使って、まとめて読み込みの指令を出すことが可能です。 ですが、http://okweb.jp/kotaeru.php3?q=1005374 でもちょっと書きましたけれど、loadMovie は「○○という画像を△△のムービークリップに読み込め」という指令を出すだけです。この点については、MovieClipLoader の loadClip といえども同じです。 「読み込め」の指令が出された時、読み込みが終わるまでスクリプトの実行がそこで止まってしまうことはなく、他の描画やスクリプトも普通に実行され、その裏で読み込み作業が並行して行われます。 例えば、for ループで5回 loadMovie や loadClip を実行すると、「 image 1 ~ 5 をムービークリップ clip 1 ~ 5 に読み込め」という5件の読み込み命令が出され、ループが終了して次のスクリプトに進みます。 読み込みの命令に従い、他のスクリプトの実行やタイムラインを動かすかたわら、裏で読み込みが実行されます。 その読み込みが終わった時はじめて、data や onLoadComplete イベントが発生するのです。 読み込みが終わるタイミングは画像の大きさや回線の速さなどで変動しますから、loadMovie や loadClip から○フレーム後で読み込みが終わると、具体的に決めることは不可能でしょう。 ですから、読み込んだ画像をただ表示して終わりではなく、読み込み後に何かを実行したいのであれば、読み込みの完了を待って先に進むといった工夫が必要になるのです。 特に読み込み関連のイベントは、タイムラインから外れて発生する割り込み信号のようなものです。これを、何とかタイムライン上で扱えるようにしようとする方法の1つが、イベント発生時にフラグに情報を保存して、フレーム間をループしてフラグを監視するというものです。 結論としましては・・・ 前回、フレーム間をループしながら1件ずつ読み込みの命令を出していたところを、今回は for ループでまとめて命令を出すことが可能になりました。 しかし、結局は読み込みの命令の出し方が変わっただけの話です。読み込み完了を待つための、フラグ等を利用したフレーム間のループを作る必要まで、なくなったわけではありません。 全部のファイルの読み込み完了を待って処理を進めるには、別途、個々の読み込み完了時に発生するイベント( onLoadComplete か onLoadInit 、普通は~Init の方を使います)時に読み込みが済んだファイル数をカウントし、この値を監視して分岐するなどしてください。 それから、MovieClipLoader のイベントについても、少々誤解なさっているようですが。 MovieClipLoader は1つのオブジェクトで複数の読み込みを管理できます。 イベントは、loadClipで受け付けた全ての読み込みでそれぞれ発生します。例えば、loadClip で5件の画像の読み込み命令を出したら、5組の onLoadStart や onLoadInit が発生します。つまり、たった1つのオブジェクトでありながら、5件の読み込みの1つ1つで、読み込みのスタートや終了、エラーが起きたかどうかなどを管理できるというわけです。 そんな器用なことができるの?と、思わず疑ってしまうほどの器用さですが、それが MovieClipLoader の偉大な点なのです。 onLoadComplete イベントも同様で、loadClip で受けた読み込みが全部終わった時に発生するのではなく、1つ1つの読み込みが終了した、その1件ごとに発生します。loadMovie や LoadVars の data ・ onLoad イベントとは少し発想が違いますので、ご注意ください。 MovieClipLoader は、読み込みに関しては MovieClip.loadMovie よりも有利な点をたくさん持っていますが、それだけに、扱いが少々難しいです。 イベントの扱い方が難しいようでしたら、とりあえずは loadMovie を使って試作し、処理の流れをつかんでから MovieClipLoader に移行してはいかがでしょうか。

teddy1014
質問者

お礼

Traceを駆使して、DPEさんのおっしゃる事を検証しました。 おっしゃった通り、for文の処理が終了した時点でonLoadComplete関数がfor文で処理した回数分実行されました。 今回は、for文で配列に格納した分だけ読込みを行ない、onLoadComplete関数でカウントアップしながら座標の決定とunload処理を行ないました。 for文を記述した2つ先のフレームで終了処理を実施する前に、onLoadComplete関数でカウントした変数と配列に格納した変数を比較して全てが終了していなければ一つ前のフレームに戻ると言うループ処理を行ないました。 MovieClipLoaderの持つイベントを有効利用したとは言えませんが、何とか今回はMovieClipLoaderを使って完成させる事にしました。 これからも、色々お教えください。 ありがとうございます。

その他の回答 (1)

  • UNAHO
  • ベストアンサー率57% (20/35)
回答No.1

正解かどうか分かりませんが私も気になっているので乗っかります。(^^;) つまり、変数やプロパティの設定は問題ないのにロードの確認やムービークリップを複製するときはなぜ出来ないのか?ということですよね。 私なりの解釈として、「そういう仕様」なんだと思います。 理由について。 一般的なプログラムの場合、1つのプログラム(ファイル)が実行されるときのポインタは1つです。複雑な処理をしていてもサブルーチンに飛んでもそのプログラム内の1カ所が実行されているだけです。つまり直列に処理がされているわけです。 しかし、Flashの場合はムービークリップやキーフレーム毎、(サブルーチン処理も含む)にマルチ処理を行います。 正しい例とはいえませんが、ループ中にサブルーチンをコールした場合、ループを処理するポインタに加えサブルーチンを処理するポインタも発生します。つまり並列処理ですね。しかしコンピュータは自体は直列処理しかできませんので見せかけ上の並列処理となります。変数を書き換えるぐらいなら問題なくてもムービークリップの生成は処理に時間がかかるのだと思われます。 この時間のかかる「処理」を変数の(軽い)処理と同様に行うとFlashプレーヤーのプログラムが過負荷のため破綻してしまうのではないかと推測されます。(ループを使う処理ということは100とか1000とかでも実使用に耐えてもらわないと困りますよね) 従って意図してこういう仕様になっているのではないでしょうか。 また、ループ処理だからというわけではなく sheet.target.duplicateMovieClip(ctr,ctr) ; dummy_loader.loadClip(var_article[0]+".jpg",sheet[0]); sheet.target.duplicateMovieClip(ctr,ctr) ; dummy_loader.loadClip(var_article[1]+".jpg",sheet[1]); sheet.target.duplicateMovieClip(ctr,ctr) ; dummy_loader.loadClip(var_article[2]+".jpg",sheet[2]); sheet.target.duplicateMovieClip(ctr,ctr) ; dummy_loader.loadClip(var_article[3]+".jpg",sheet[3]); . . . としても同じ結果になると思います。 私もループ処理できれば楽なのにと思っています。 何かご存じであれば私も知りたいと思っています。

teddy1014
質問者

お礼

回答ありがとうございます。 Structuredプログラムとイベントドリブン型のプログラムの典型的な違いのような気がします。 ループで行なう処理とそこから発生するイベントとは、順序は無いと言う事だと思います。 DPEさんからのアドバイスは全くその通りです。

関連するQ&A

専門家に質問してみよう