サイトトップ

Director Flash 書籍 業務内容 プロフィール

Macromedia Flash非公式テクニカルノート

MovieClip.loadMovieで外部ファイルを読込む

ID: FN0307007 Product: Flash

Platform: All
Version: 5.0 and Above

1. MovieClip.loadMovieメソッド
外部ムービーファイルを読込むには、MovieClip.loadMovieメソッドを使います。Flash MXからは、SWFムービー以外に、JEPGファイルも読込めるようになりました。

JPEG画像が読込めるのは、Flash MXのアプリケーションというより、Flash Player 6の追加機能です。したがって、Flash 5で作成したムービーでもFlash Player 6上でなら、MovieClip.loadMovieメソッドを使ってJPEG画像の読込みが可能です(完全にサポートされる機能とはいえないかもしれません)。

同階層にある外部SWFファイルtest.swfを、メインのタイムラインからMovieClipインスタンスmy_mcにロードする場合には、フレームアクションをつぎのように記述します(スクリプト001)。

スクリプト001■MovieClip.loadMovie()メソッドで外部SWFをロード

// _root: メインのタイムライン
// フレームアクション
this.my_mc.loadMovie("test.swf");


読込む外部ファイルのURLは、絶対パスまたは相対パスで指定します。相対パスを使う場合は、FlashのSWFファイルではなく、SWFファイルの埋込まれたHTMLファイルがパスの起点になります。上記のサンプルスクリプトは、相対パスの例です。

パスの起点は、厳密にはブラウザに依存します。実際Internet Explorer 4.5/Macintoshでは、パスの起点がSWFファイルになるという不具合がありました(Macromediaテクニカルノート「Macintosh Internet Explorer 4.5 でおこる不具合」参照)。この問題は、Ver.5.0から解決されています(同「Macintosh Internet Explorer 5 で改善された問題・改善されていない問題」参照)。

ロードされる外部ファイルは、ターゲットに指定したMovieClipの基準点を左上隅として配置されます。ですから、ターゲットのMovieClipは、初めから基準点を左上隅に設定しておくと、位置が合わせやすいです。

2. 外部ファイルの読込みを待つ
MovieClip.loadMovieメソッドを使ってロードしたMovieClipインスタンスに対して、プロパティの取得・設定をしたり、メソッドの実行をしたい場合があります。その処理の内容によっては、ファイルのロードが完了するのを待つ必要があります。

たとえば、位置座標のMovieClip._xMovieClip._yプロパティなら、読込みの完了を待つ必要はなく、MovieClip.loadMovieメソッド実行直後に設定することができます。ところが、幅や高さのMovieClip._widthMovieClip._heightプロパティは、ロード実行直後に値を調べると、外部ファイルを読込む前の元のMovieClipの値が返されてしまいます。したがって、読込んだファイルのサイズを取得して処理を行う場合には、読込みを待つ必要があります。あるいは、MovieClip.gotoAndPlayメソッドで指定フレームから再生したい場合、メソッド自体は使用可能です。しかし、指定フレームの読込みが済んでいなければ、メソッドは空振りに終わり、何も実行されません(メソッドは無視されます)。

外部ファイルのロード完了を待つには、onClipEvent (data)イベントハンドラアクションを使用します。ただし、onClipEvent (data)イベントハンドラでは、ひとかたまりの「各データセクションが読み込まれるたびに、dataイベントが繰り返し発生します」(Flash MX「ActionScript辞書」のonClipEventの項参照)。つまり、容量の大きなSWFファイルを読込むときには、dataイベントが何度も発生することがあるのです。

onClipEvent (data)イベントハンドラアクションを、MovieClip.loadVariablesメソッドのロード待ちとして使用する場合には、「最後の変数がロードされたときにdataイベントが1回だけ発生します」(Flash MX「ActionScript辞書」のonClipEventの項参照)。つまり、dataイベントの発生が、ロードの完了を意味します。

そこで、onClipEvent (data)イベントハンドラ内で、データがすべて読込まれたかどうかの判定の処理が必要になります。その判定のために使用するのがMovieClip.getBytesTotalMovieClip.getBytesLoadedの2つのメソッドです。前者はターゲットに指定した MovieClip全体のサイズを、後者はロード(ストリーミング)されたバイト数を返します。

ロードされたバイト数がMovieClip全体のバイト数に達したときに、ムービーのロードが完了したことになります。onClipEvent (data)イベントハンドラの中にifアクションを記述して、この2つの値を比較して判定すればよいでしょう。

外部SWFムービーのロードが完了するのを待って、指定フレームから再生するサンプルスクリプトが以下です(スクリプト002)。外部SWFムービーのロードは、メインのタイムラインのフレームアクションから実行します。SWFムービーをロードするターゲットは、メインのタイムラインに配置したMovieClipインスタンスmy_mcです。_root.my_mcに、ロード待ちのMovieClipアクションを設定します。

スクリプト002■onClipEvent (data)ハンドラで外部ファイルのロードを待つ

// _root: メインのタイムライン
// フレームアクション
this.my_mc.loadMovie("test.swf");

// MovieClip: _root.my_mc
// MovieClipアクション
onClipEvent (data) { //  [1] 各データセクションが読込まれるたびに実行
  // [2] 総データサイズが0より大きく、かつロードしたバイト数が総データサイズに達したことを確認
  if (this.getBytesTotal()>0 && this.getBytesLoaded()>=this.getBytesTotal()) {
    this.gotoAndPlay("start");  // [3] 外部SWFムービーのロード完了時の処理(指定フレームから再生)
  } else {
    this.stop();  // [4] 外部SWFムービーのロード完了までの処理(第1フレームで停止)
  }
}

[1] onClipEvent (data)イベントハンドラアクションで、データの読込みをイベントとして受取ります。外部SWFムービーをロードするので、dataイベントは複数回発生する可能性があります。

[2] MovieClip.getBytesTotalメソッドが返すロードしたSWFムービー全体のサイズと、MovieClip.getBytesLoadedメソッドから取得した読込み済みバイト数とを比較して、ロードの完了を確認します。

なお、MovieClip.loadMovieメソッドで外部SWFムービーのロードを開始した瞬間には、環境によって「MovieClip.getBytesTotal」メソッドが0を返すことがあります。そうすると、その時点では「MovieClip.getBytesLoaded」の戻り値も0なので、2つの値の比較だけではロードが完了したという判定になってしまいます。そこで、if条件をひとつ追加して、MovieClip.getBytesTotalメソッドの戻り値が0より大きいことを確認しています。

[3] ロード完了が確認できたら、完了後の処理を実行します。このサンプルでは、フレームラベル"start"に移動して、ムービーを再生します。

[4] ロード待ちの間、行う処理を記述します。ここでは、再生が先に進まないように、再生ヘッドを停止しています。

3. MovieClip.loadMovieで外部ファイルを読込む際の注意
外部ファイルをMovieClip.loadMovieメソッドで読込むと、ターゲットインスタンスにスクリプトで設定したプロパティやメソッドなどはすべてクリアされます。これは、プロパティやメソッドをMovieClip.loadMovieメソッドの実行前に定義した場合ばかりでなく、実行直後に設定した場合も同じです。

たとえば、ロードを実行する前にインスタンスの位置座標をそのMovieClipの変数に設定しても、ロードした時点で変数はクリアされて未定義(undefined)になってしまいます。ですから、ロード中の処理をステージ外で行って、読込み終わったら元の位置に戻そうと思っても、変数に設定した位置座標はメモリから消えているということになります。

ステージ外でロード中の処理を行いたい場合には、元の座標から定数を差引く(たとえば、_x -= 1000とする)ことが考えられます。元の位置に戻すには、その定数を逆に加えればよいでしょう。

外部SWFムービーの第1フレームは表示せずに、直接指定フレームから再生したいという例が考えられます。ご参考までに、サンプルSWFムービー(再生にはFlash Player 6以降が必要です)とソースのFLAファイル(Flash MX用/Zip圧縮/約295KB)を掲げます。

MovieClipの外部からインスタンスに設定したイベントハンドラメソッドも、外部SWFをロードするとクリアされます。イベントハンドラメソッドが外部SWFムービー内のフレームアクションに記述してあれば、もちろんロード後も有効です。

インスタンスに設定したMovieClipアクションは、外部ファイルをMovieClipにロードしてもそのまま残ります。ですから、イベントハンドラメソッドなどのフレームアクションを中心としたMXスタイルのスクリプティングでも、onClipEvent (data)イベントハンドラアクションは引続き使用する価値があります。

MovieClip._widthMovieClip._heightプロパティについては、外部ファイルの読込み実行時には、元のMovieClipインスタンスの値を返します。その後プロパティはクリアされ、外部ファイルがロードされるとそのサイズに更新されます。ですから、読込み後のインスタンスの幅や高さを変更したい場合には、値が更新された後に設定する必要があります(更新前に設定すると、元のMovieClipインスタンスを基準に変形を行うため、意図したサイズに設定できません)。

MovieClip._width/MovieClip._heightの値が更新前で、空つまり値0のときにサイズ指定を行うと、ロードした外部ファイルが表示されません。

たとえば、MovieClip.createEmptyMovieClip()メソッドで作成したインスタンスや空のMovieClipをターゲットにMovieClip.loadMovie()メソッドを呼出すと、その直後はMovieClip._width/MovieClip._heightプロパティの値は0です。外部ファイルがロードされれば、それらのプロパティは読込んだコンテンツの値に更新されます。

ところが、まだ値0の段階でMovieClip._width/MovieClip._heightを使ってサイズ指定をすると、空なので0以外の値に設定することができません。その結果、0が指定されたものとして扱われ、外部ファイルをロードしてもそのプロパティ値は更新されません。MovieClip._widthまたはMovieClip._heightが0になれば、当然コンテンツが表示されないということになります。

MovieClipの定義済みプロパティについては、個別に確認する必要があります。MovieClip._xMovieClip._yプロパティは、前述のとおり、ロード実行の前後をとおして問題なく取得・設定が可能です。これに対して、MovieClip._visibleプロパティは、読込み前あるいはその直後にfalseに設定しても、ロードされればtrueにリセットされます。

なお、onClipEvent (load)ハンドラでMovieClip自身をターゲットにloadMovieを実行することは避けましょう。外部SWFムービーをロードすると、MovieClipの内容が置き換わるので、onClipEvent (load)イベントハンドラが1度実行されます。したがって、このハンドラの中でそのMovieClip自身をターゲットとしてMovieClip.loadMovieメソッドを実行していると、無限に同じ処理を繰返すことになってしまいます。

ロードの処理が実行されたことをMovieClipインスタンスの変数(フラグ)に記録して、処理の循環を回避することもできません。MovieClipがロードされると、ユーザーが設定した変数やプロパティはクリアされてしまうからです。しいてこの方法を採るとするなら、変数はインスタンスの外部に設定する必要があります。ただ、スクリプトとしてあまりスマートとはいえないでしょう。

さらに、複数の外部ファイルをMovieClip.loadMovie()メソッドで、同時に読込むべきではありません。サーバーが同時に読込めるファイル数には制限があり、仮にその制限内あってもタイムアウトの発生などロードを妨げる要因が発生しやすくなります。外部ファイルのロードはひとつずつ、その完了を確認したうえで行っていくスクリプティングが必要とされます。Flash Player 7以降を対象とする場合には、MovieClipLoaderクラスを利用するのが簡単でしょう。

ロードした外部SWFのライブラリシンボルのインスタンスを、読込んだベースのムービー内にMovieClip.attachMovieを使って配置することはできません。

Flash MX 2004オンラインヘルプ[ActionScriptリファレンスガイド]の[MovieClip.loadMovie()]の項に、外部SWFをロードするターゲットのインスタンスにMovieClip._lockrootプロパティをtrueと設定することにより、「ロードされたムービーのライブラリにはアクセスでき」るかのように説明されているのは誤りです。

そのような場合には、共有シンボルを使用する必要があります。

_____

作成者: 野中文雄
更新日: 2005年6月20日 空(サイズ0)のターゲットにサイズ指定した場合の注釈を追加。レイアウトを一部修正
更新日: 2005年4月24日 複数ファイルをロードする場合の記述、および外部SWF内のシンボルにアクセスする場合の注釈を追加
作成日: 2003年7月25日


Copyright © 2001-2006 Fumio Nonaka.  All rights reserved.