- ベストアンサー
パブリッシュ設定でFlash Player 6 → 7に変更したら一部動作しなくなった
- パブリッシュ設定で書出しバージョンを6から7に変更したら、一部の動作が正常に行われなくなりました。
- 変更した理由は、外部のjpegファイルをターゲットMCにロードするためでしたが、loadMovie()メソッドではプリローダーの動作が正常に行われないことが分かりました。
- そのため、loadClip()メソッドを使うことにしたのですが、Flash Player 7で書き出すと一部の動作が停止してしまいます。変数のvar宣言や型の指定を追記することで解決できる可能性がありますが、他にも注意すべき点はあるでしょうか。ガイドブックや他の開発者の経験を参考にしたいです。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
loadClip の使い方を間違えていませんでしょうか? loadClip は loadMovie とは違い、new MovieClipLoader で MovieClipLoader クラスのオブジェクトを作らないと使用できません。 基本的な読み込みのスクリプトは、次のようになります。 (↓各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください) //オブジェクトを作成 load_obj = new MovieClipLoader(); //画像の読み込み load_obj.loadClip( "***.jpg" , target_mc ); MovieClipLoader で読み込んだ時は、このクラスが持っている getProgress という機能(メソッドといいます)か、特有のイベント onLoadProgress を利用して進捗状況を把握できます。 onLoadProgress は読み込んだデータがハードディスクに書き込まれる度に発生するイベントですが、オフラインでは正常に動かないので、getProgress の方が扱いやすいです。 ただし、getProgress は戻り値が2つあります。値の受け取り方や参照の仕方にはご注意ください。 読み込みの完了を待つ方法は様々ですが、フレーム間をループして作ると完了率の表示なども作りやすいかと思います。 フレーム間をループする方法では、フレームの構成は次のようになります。 フレーム1:読み込み開始 フレーム2:完了を待つためのフレーム。スクリプトはなし。 フレーム3:読み込み終了判定 フレーム4:普段はここを表示する この流れに沿ってスクリプトを考えますと、大体、次のようになります。 スクリプトはフレーム1と3に設定します。 ●フレーム1 //オブジェクトを作成 load_obj = new MovieClipLoader(); //画像の読み込み load_obj.loadClip( "load_clip.swf" , target_mc ); //完了率算出用オブジェクトを作成 prog = new Object(); ●フレーム3 //進捗状況を取得 prog = load_obj.getProgress( target_mc ); loaded = prog.bytesLoaded; total = prog.bytesTotal; //完了率を算出 per = Math.floor( loaded / total * 100 ); //完了を待つ if( per < 100 ) { gotoAndPlay( _currentframe - 1 ); } //完了したら、次のフレームでタイムラインを止める else { nextFrame(); } 先述の通り、MovieClipLoader の getProgress メソッドには戻り値が2つあります。 関数は戻り値を1つしか返せないため、getProgress は、汎用型である Object 型というタイプの変数に値を2つ入れ、この変数1つだけを返すように設計されています。 たとえるなら、カゴを1つ用意してその中に複数の値を入れ、カゴごとやりとりしているようなものです。 上記のスクリプトでは、変数 per に完了率がパーセントで入ります。 プログレスバーや完了率の表示などにご利用ください。 完了率はフレーム3まで表示すればOKです。 --------------------------------------------------------- ところで、loadMovie で読み込んだ場合でも、進捗状況を取得する方法は、あるにはあります。 普通のプリロード画面は、_totalframes と _framesloaded プロパティを見てフレーム数を把握する方法と、getBytesTotal と getBytesLoaded メソッドで容量を把握する方法の2通りの作り方があります。 getBytes*** メソッドは実はムービークリップであればどれでも持っているもので、ムービークリップに読み込まれる画像や swf ファイルの総容量とロード済み容量を教えてくれます。 Flash ではムービー自体も _root という名前のムービークリップとして扱いますから、_root の getBytes*** メソッドではムービー全体の読み込みの進捗状況が把握できるというだけなのです。 target_mc に画像を読み込んだ場合、この読み込みの進捗状況は、target_mc が持っている getBytes*** メソッドで把握できます。 loadMovie、MovieClipLoader の loadClip のどちらで読み込んでも利用できます。 上記のスクリプトで、フレーム1の画像を読み込む部分を //画像の読み込み loadMovie( "load_clip.swf" , target_mc ); フレーム3の進捗状況を取得する部分を //進捗状況を取得 loaded = target_mc.getBytesLoaded(); total = target_mc.getBytesTotal(); このように変更しても、同じように動作します。 フレーム1のスクリプトを変更せず、loadClip で読み込むようにしていても同じです。 単に、画像を読み込みその進捗状況を把握したいだけなら、使い方がややこしい MovieClipLoader をあえて使う理由はないのかもしれません。 しかし、MovieClipLoader にできて loadMovie にはできないこともたくさんあります。 loadMovie は、読み込みの命令を出したら、あとは知らんぷりです。 一方 MovieClipLoader は、読み込みを始めてから終了するまで終始その処理を監視していて、処理の各段階ごとにイベントを発生させて状況を知らせてくれます。 先の onLoadProgress というイベントもそのうちの1つですが、他にも様々なイベントがあり、loadMovie よりも細かくロードの状況を把握できます。 特に、回線の都合などでダウンロードが失敗した時やファイルが見当たらなかった場合に、onLoadError というイベントでエラーの発生を知らせてくれるのは、loadMovie にはない機能です。 MovieClipLoader では、1つのオブジェクトでいくつもの読み込みを管理できます。 loadMovie は1件分の読み込み命令しか出せません。 例えば5件の読み込みがあり、読み込み完了時に何かをしたい時は、5件分の指示を出しておかなければなりません。 その点 MovieClipLoader なら、最初に1度、読み込みが済んだ時にはこうしてほしいと約束しておくと、5件の読み込み全てに同じ処理を施してくれます。 MovieClipLoader には、このような特長があります。 機会がありましたら、loadMovie ではできない、エラー発生時の対策がある読み込みなども研究してみてください。
その他の回答 (2)
- DPE
- ベストアンサー率85% (666/776)
#2のお礼欄にあるスクリプトをざっと試してみたところ、HTML に組み込んでも動きましたよ。 「ダウンロードのシミュレート」で動いたことから考えても、スクリプトは問題ないと思います。 ただ、サーバーにアップロードしてブラウザで見ると、バーが伸びたのは最初の1回だけでした。つまり、2回目以降はキャッシュから拾われているようです。 画像も swf ファイルもローカルにあり、オフライン環境で見る場合は読み込みは一瞬で終わるので、ブラウザで見てもバーは伸びません。これは正常な動作です。 キャッシュから拾われないようにするには、適当な数字を作って URL に ? でダミーの引数として連結する方法があります。 xChangeIllust 関数を、次のように変更してみてください。 xChangeIllust = function() { var rnd , filename; //キャッシュからの読み込み防止: //適当な数字を連結して、毎回違うURLを作る rnd = Math.floor( Math.random() * 1000 ); filename = "1.jpg?dummy=" + rnd; //画像読み込み開始 loadMovie( filename , _root.loader_mc ); //ルートのプログレスバーMC ((preloader_mc)) 内のメソッド呼び出し _root.preloader_mc.xPreloader(); }; 例えば、 1.jpg?dummy=50 と 1.jpg?dummy=100 は違う URL と見なされますから、キャッシュからは拾われません。 なお、「ムービープレビュー」では URL オープンエラーになります。ブラウザで確認してみてください。 ところで、プリローダが動作しないことで、どのような不具合(例えば、完了率が 100 %にならないためにムービーが先に進まない・バーが表示されたままになる・しばらく何も表示されない状態が続くなど)があるのでしょうか? バーのアニメがなくいきなり画像が表示されるのは、これはキャッシュから拾われているだけなので、他に問題がなければ特に気にしなくても構わないと思います。 キャッシュの問題だとすると、onClipEvent(data) や MovieClipLoader を使ったとしても、完了率がいきなり 100 %になりますから、バーは伸びません。 また、画像の容量にもよるのですが、ADSL などの速い回線をお使いの場合ですと読み込みが一瞬で済んでしまい、スクリプトに誤りはなくてもバーが伸びていかないようにみえることもあります。 これは、何か重い swf ファイルや JPEG 画像を作って試してみると分かりやすいです。 さしあたって、原因として思いつくのはこんなところですが、いずれかに該当しませんでしょうか?
お礼
いつも有り難うございます。動きました!動いたのですが、当方制作メインはMacでして、ブラウザは主にFirefoxを使っています。Safari上でFlashの挙動はギクシャクして気持ち悪いので使ってないのと、Firefoxの方がWindows+IE上でのFlashの動きとほぼ同じなので(マシンスペックにより変動はありますが)という理由です。で、WindowsのIEで動作させてみた所、プログレスバーは正常に動きました。外部jpgファイルは30枚あり、それぞれ一回目はバーが伸び、二回目以降はキャッシュを拾い、バーは出ませんでした(連打すればたまにチラッと見えるときもありますが)。 今出来る限りで動作チェックしてみました所、 ↓動作しない MacOSX tiger FlashPlayer ver7.0.24.0 Firefox Safari WindowsXP FlashPlayer ver7.0.19.0 Firefox ↓操作した WindowsXP FlashPlayer ver7.0.19.0 InternetExplorer RealOnePlayer でも、上記全ての環境で、今回と同一サイト内ですが、プログレスバーは正常に動作しています。ただしロードしているのはswfファイルで読み込みもloadMovieNum()と_level指定ですから、当たり前ですね^^。以下アクションクリプト辞書からloadMovei()の抜粋ですが 【ヒント: ダウンロードの進捗状況を監視する場合は、この関数の代わりに MovieClipLoader.loadClip() を使用してください。】 とあるように、やはりどの環境でも正常に動作させるには、DPEさんがおっしゃられたようにMovieClipLoaderクラスで処理した方が良いのでしょうね。 PS. キャッシュを拾わせない方法があるのですね。また一つ勉強になりました。2回目以降もプログレスバーを意図的に出したいときなどに使えそうですね。ありがとうございました。
- DPE
- ベストアンサー率85% (666/776)
#1です。 loadMovie と getBytes*** に変更して、「ムービープレビュー」の「ダウンロードのシミュレート」およびサーバー経由の両方で確認してみましたが、進捗状況は正常に把握できました。 オンライン環境や loadMovie と組み合わせたから動かないということではなさそうです。 お礼欄のスクリプトを拝見して思ったのですが。 target_mc.onEnterFrame = function() { //進捗状況を取得 loaded = this.getBytesLoaded(); total = this.getBytesTotal(); : }; というような書き方をなさっていませんでしょうか? これこそ Flash の仕様なのですが、ムービークリップに画像や swf ファイルを読み込むと、ムービークリップの一部の属性( _visible など)や持っていた変数等の初期化が行われます。 on*** = function() ・・・の書き方は一種の変数のようなものですから、loadMovie や loadClip を実行した時点でクリアされてなくなってしまい、正常に動作しなくなります。 この書き方をする限り、getBytes*** でも MovieClipLoader の getProgress でも、進捗状況は把握できません。 どうしても on*** = function() ・・・の形式で定義する場合は、_root またはダミーのムービークリップを作るなどして、target_mc 以外のムービークリップの onEnterFrame イベントハンドラを借りて定義してはいかがでしょうか。 もしくは、target_mc に (↓各行頭に全角のスペースが入っています。コピーする際はご注意ください) onClipEvent(data) { //進捗状況を取得し、完了率を算出 loaded = this.getBytesLoaded(); total = this.getBytesTotal(); per = Math.floor( loaded / total * 100 ); //完了を待って、先に進む if( per >= 100 ) { /*ここに、読み込み完了時の処理を書く*/ } } このように、onClipEvent アクションと data イベントを使って設定してみてください。 onClipEvent で設定したスクリプトは、読み込みを実行しても削除されることなく残ります。 data は、ムービークリップに外部からデータを読み込む時に発生するイベントです。loadVariables では最後の変数が読み込まれた時に1度だけですが、loadMovie の時は読み込みの演算が終わるまで数回にわたって発生します。 ただし、data イベントを使ったスクリプトはオフラインでは正常に動きません。「ムービープレビュー」では「表示」→「ダウンロードのシミュレート」にチェックを入れて動作を確認してください。
お礼
DPE様。毎回ほんとに有り難うございます。なるほどonClipEvent(data)というのは、シンプルでよさそうですね。早速サンプルつくって試してみます。スクリプトもスッキリしていて使いやすそうですね。当方ActionScript以外はまったく書いたことがありませんし、しかも独学なので、やっぱり根本的な基礎知識や基礎概念が一部欠落してしまっているのでしょうね。がんばります。 参考までに実際のflaファイルから、問題のコードを貼付けます(余分なコードは削除)。trace()の結果も含め、目を通して頂ければありがたいです。「ムービープレビュー+シミュレート」で、プログレスバーは読み込みに従ってちゃんとのびてゆきます。うーん。どこがダメなんでしょうか?? ●ボタン on(release)で ルートのxChangeIllust() を呼び出し ●ルート 1フレーム xChangeIllust = function () { //画像読み込み開始 読み込み先の loader_mcはルートに配置(クリップアクション記述無し) loadMovie("1.jpg" , _root.loader_mc); //ルートのプログレスバーMC ((preloader_mc)) 内のメソッド呼び出し _root.preloader_mc.xPreloader(); }; ●preloader_mc(これがプログレスバーです) 1フレーム xPreloader = function () { this.onEnterFrame = function() { nTotal = _root.loader_mc.getBytesTotal(); nLoaded = _root.loader_mc.getBytesLoaded(); nPercent = Math.floor(nLoaded/nTotal*100); trace(nPercent)//プレビューではちゃんと数字がトレースされます if (nPercent<100) { this._xscale = nPercent; } else if (nPercent>=100) { this._xscale = 0; trace("end"); delete this.onEnterFrame; } }; }; ●トレース結果 0 3 6 6 10 -----中略----- 97 97 100 end
お礼
DPE様、とても分かりやすいアドバイス有り難うございました。だいぶ勘違いしていたようです。普段はversion6書出しで作っているので、このあたりはあまり理解できていませんでした(今もですが)。でもスクリプトの流れはちょっと分かりかけたような気がします。playerの普及率などにより、いずれはversion7や8へと移行して行くでしょうから、本腰入れて勉強してみます。 ちなみにムービープレビューではloadMovie("---",---mc)で、getBytesLoadedとgetBytesTotalでプログレスバーはこちらの意図通りに動作しましたが、html上では動作しませんでした(ローカルでもサーバでもです/version6書出し)。これは仕様なのでしょうか。うーん。また混乱しそうですが、もう一度冷静に取り組んでみます。DPE様のアドバイスをもとに以下のスクリプトを考えました。実際にFlash内で動作させたわけではありませんが、考え方としては合っているでしょうか。DPE様も、お忙しいとお察しいたします。以下に対するアドバイスは無くても気に致しません。もうすでに十分すぎるアドバイスをいただいてますから^^。有り難うございました。 ●ステージの任意の場所に loader_mc MCを配置 ●ステージの任意の場所に bar_mc MCを配置 プログレスバーです ●ステージの任意の場所に load_btn ボタンの機能をするMCを配置 ●load_btnには、 on(release){ //エラーになるでしょうが、ご説明用ですので。nが増えて行く処理とお考え下さい n++; _root.xChangeImage(n); } ●メインフレームの1フレーム xChangeImage = function(n); load_obj = new movieClipLoader(); prog = new Object(); path = n+".jpg"; load_obj.loadClip(path, _root.loader_mc); _root.loader_mc.onEnterFrame = function(){ _root.loader_mc.loaded = prog.bytesLoaded; _root.loader_mc.total = prog.bytesTotal; per = Math.floor(loaded/total*100); if(per < 100){ _root.bar_mc._xscale = per; }else if(per >= 100){ _root.bar_mc._xscale = 0; delete _root.loader_mc.onEnterFrame; } } }