- ベストアンサー
外部ファイルの先読み
メインのページにランダムで画像が変わるよう rnd = Math.floor(Math.random()*10)+1; _root.photo.loadMovie("photo"+rnd+".jpg"); とスクリプトを入れました。 ローカルだともちろん問題ないのですが、サーバーにアップして確認してみると、表示するときになって読み込むものですからちょっと遅れて表示されてしまいます。 これを回避するために先読みする方法がありましたら教えていただけますでしょうか? ちなみに始めにロード画面が表示されるのですが、その完了と一緒に外部ファイルの画像も読み込みが終わるようにしたいと思っています。 よろしくお願いします。 FLASH MX/WINDOWS XP
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
画像を動的に読み込むにはムービークリップが必要です。 このムービークリップがロード画面の後で出てきて、読み込みの命令もムービー本体の読み込みが済んでから実行されるために、トップページの画像の表示が遅れるのです。 ということは、要はこのムービークリップをフレーム1から登場させ、トップページより先に loadMovie で読み込みの命令を出しておけばいいことになります。 loadMovie のスクリプトよりも画像を読み込むムービークリップが後に読み込まれると、ムービークリップが未定義になって失敗するおそれがあります。 また、画像の読み込みがムービー本体よりも先に終わった場合は画像が表示されてしまいますから、最初は非表示にしておき、ムービーのスタート時に表示する工夫が必要です。 Flash MX から使えるようになった、空のムービークリップをスクリプトで生成する createEmptyMovieClip や onLoad = function ・・・というスタイルのスクリプトを利用したり、スクリプトだけで何とかする方法もなくもないのですが、loadMovie を実行した時に無効になったりと、面倒な点も多々あります。 画像のサイズが固定でしたら、ステージに予め、画像を読み込むためのムービークリップを配置しておくと便利です。画像が収まるスペースが分かりますし、ムービーも編集しやすくなります。 フレーム1に大きなデータが書き出されていたり容量の大きなシンボルが配置されていると、フレーム1の読み込みに時間がかかって、その先のロード画面がなかなか出てこなくなります。 ですが、画像を読み込むためのムービークリップ1つくらいなら容量はたかが知れていますから、フレーム1に配置しても問題はないと思います。 フレーム1には画像を読み込むためのムービークリップだけを画像が収まる位置に配置し、他のロゴやボタン等はロード画面の次のフレームから出すようにします。 このあたりは、レイヤーを分けると管理しやすいかと思います。 ちなみに、空のシンボルを配置しておき、画像の読み込み完了後にスクリプトで位置を決める方法もあります。 これらのことを合わせて考えますと、次のような構成になります。 画像の受け皿となるムービークリップ” photo ”をフレーム1から配置します。photo はムービー本編が再生されるまで、ずっとステージに存在しているようにします。 photo には onClipEvent(load) を使って、最初に非表示にするスクリプトを書きます。 load イベントは画像の読み込みが終了した時にも発生します。 onClipEvent(load) の中で loadMovie を実行すると、画像の読み込みの終了と同時に再度読み込みが始まり、画像の読み込みがいつまでも終わらなくなるのでご注意ください。 loadMovie はフレーム2に書きます。フレーム1で登場する photo はフレーム2では既に存在しているはずですから、loadMovie が失敗する心配もありません。 読み込みの進捗状況を表すプログレスバーや「 Now Loading ○%」といった情報を出す場合は、フレーム3から4まで表示します。 ロードの終了を待つスクリプトはフレーム4に書き、フレーム3と4の間をループしながら完了を待ちます。 スクリプトにしますと、大体、次のようになります。 (↓各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください) ●ムービークリップインスタンス photo に設定するスクリプト onClipEvent(load) { //最初は非表示にする this._visible = false; } ↑先述の通り、このスクリプトは loadMovie での読み込みが終わった時にも実行されます。 つまり、読み込まれた画像は、読み込み完了と同時に非表示になります。 ●フレーム2 //画像をランダムに選択して読み込む rnd = Math.floor( Math.random() * 10 ) + 1; photo.loadMovie( "photo" + rnd + ".jpg" ); ●フレーム4 //完了率の算出 //ムービー本体と画像の合算で出す total = _root.getBytesTotal() + photo.getBytesTotal(); loaded = _root.getBytesLoaded() + photo.getBytesLoaded(); per = Math.floor( loaded / total * 100 ); //読み込み完了を待つ if( per < 100 ) { gotoAndPlay( _currentframe - 1 ); } ●フレーム5 //画像を表示 photo._visible = true; フレーム4では完了率を出しています。 フレームに書かれたスクリプトが実行されるのは、再生ヘッドがそのフレームに来た1度限りです。 Flash の仕様上、同じフレームに続けて再生ヘッドをセットすることはできないので、フレーム3と4の間を往復しながらスクリプトを繰り返し実行し、読み込みの完了を待ちます。 完了率は変数 per に、パーセントで入っています。ダイナミックテキストでの完了率の表示やプログレスバーの描画にご利用ください。 総容量と読み込まれた容量から割合を求めるポピュラーな計算方法ではありますが、解説書や解説サイトで見かけるものとは少し違います。 なぜかといいますと、今回は photo に読み込まれる画像の容量も考慮した完了率を求める必要があるからです。 ムービー全体が画像よりも容量が大きい場合は、ムービーと画像を並行して読み込むと画像の読み込みの方が先に終わります。これなら、ムービー本体( _root )の容量だけで完了率計算して先に進んでも何とかなります。 しかし、例えばムービー本体が 100 キロバイトくらいしかなく、画像がその倍の 200 キロバイトのものだったしたら、_root の容量だけで完了率を出して先に進むと、画像の読み込みが終わらないうちにムービーが始まってしまいます。 完了率 100 %と表示されてムービーが始まったにもかかわらず、トップページの画像が読み込み中では意味がありません。 上記のスクリプトでは、_root と photo の総容量と読み込まれた容量をそれぞれ取得して合算で完了率を出し、この完了率が 100 %になるのを待ってから先に進んでいます。 photo に読み込まれた画像は、最初は非表示( _visible プロパティが false )になっています。 読み込みが完了すると次のフレーム(フレーム5)に進みますから、ここで _visible プロパティを true にして画像を表示します。 フレーム4の if 文に else 句を付けて _visible プロパティを書き換えてもいいのですが、プログレスバーや完了率を表示している場合は、ほんの一瞬ですがこれらの表示と画像が重なって表示されてしまいますので、フレーム5で表示する方がオススメです。 --------------------------------------------------- この方法ですと、確かにロード画面の終了と同時に画像が表示されるのですが、トップページから他のフレームに切り替えたなどでムービークリップ photo が一旦ステージから消え、再度トップページのフレームに戻ってきた時には画像が読み込まれず、表示されません。 ページ全体が Flash でできているサイトの場合は、必要に応じて photo を非表示にしてステージに常時残しておくなど、再度読み込まなくても済むようにする工夫が必要になるかと思います。 Flash がトップページの看板的な役割で、Flash 内のボタンや HTML のリンクから別の HTML ページを表示する構成のサイトでは、他のページからトップページに戻ってきた時には Flash もフレーム1から読み込みになりますから、画像は再度読み込まれます。 ただし、この時は最初に読み込んだ画像とは違うものが読み込まれる可能性はあります。 この話は長くなりますので、またの機会に。
その他の回答 (1)
こういう場合,本当は定石みたいなものがあるかもしれません。 でも知らないので考えついた1つの方法です。 ロード画面が実際にどうなっていて, 何フレーム使用されているのかわからないので, 正確にはかけませんが, 1フレーム目から,インスタンス名「photo」MCをステージ上に登場させて置いて, さらに1フレーム目のフレームのスクリプトとして, ------------------------------------ _root.photo._alpha = 0; rnd = Math.floor(Math.random()*10)+1; _root.photo.loadMovie("photo"+rnd+".jpg"); ------------------------------------ 何フレームかわかりませんが,ロード画面明けのフレームに ------------------------ _root.photo._alpha = 100; ------------------------ と書かれてはどうでしょうか。 _visible = false; を上のように使おうかと思ったのですが, これを使うと,怪奇現象が起こるので,今回はアルファの方をお薦めします。 _visible = false;を使いたい場合は, 1フレーム目のフレームスクリプトで, ------------------------------------ rnd = Math.floor(Math.random()*10)+1; _root.photo.loadMovie("photo"+rnd+".jpg"); ------------------------------------ と書いて, 「photo」MCに ----------------------------------- onClipEvent (load) { _root.photo._visible = false; } ----------------------------------- と書いて, ロード画面明けのフレームに ------------------------ _root.photo._visible = true; ------------------------ としてください,でないと変になります。 何故かは説明出来ません。 ※SWFの重さや,リンケージの設定によっては_alphaでもうまく行かないかもしれません。
お礼
すぐに回答していただきありがとうございます。お礼が遅くなり大変失礼しました。また私の説明不足でご迷惑おかけしました。 お二人から回答いただきどちらも試してみましたが、ちょっと上手くいきませんでした。 まだまだ私の勉強不足なので、回答いただいたことを今後につなげていきたいと思います。 回答ありがとうございました。
お礼
すぐに回答していただいたにも関わらずお礼が遅れてしまい申しわけありません。 回答いただいた後何度時間を見つけてが回答の様に挑戦してみたのですが、そもそもの作りが悪いのか私の理解力が足らないのかいまいちうまくいきませんでした。 もうちょっと時間をかけて作製して行きたいと思います。 回答していただきありがとうございました!