サイトトップ

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

Adobe Flash CS3 Professional ActionScript 3.0

□Tech 02 外部データをロードする

Flashムービーで使われるサウンドやMovieClipシンボル、画像、テキストデータといった素材は、必ずしもFLAファイルにすべて入れておかなければならないということはありません。それらを外部ファイルにしてあとから読込むようにすれば、起動のSWFファイルはサイズを小さくできます。また、ユーザーが素材のすべてを視聴しない場合には、無駄なロードが避けられます。

02-01 外部MP3サウンドを再生する
サウンドは、MP3ファイルを外部から読込んで、再生することができます。このとき使うのが、Soundクラスです。Sound.load()メソッドで指定されたURLのMP3ファイルをロードし、Sound.play()メソッドによりサウンドの再生を開始します。

【Soundクラスで外部MP3ファイルをロードして再生する手順】
var 変数:Sound = new Sound();
変数.load(URLRequestインスタンス);
変数.play();

ひとつ注意すべきことは、Sound.load()メソッドの引数に渡す外部MP3ファイルのURLは、URLRequestインスタンスで指定するということです。URLRequestクラスのコンストラクタには、引数としてURLを文字列で渡します。すると、SWFファイルやそれが埋込まれたHTMLドキュメントと同じ場所にあるMP3サウンドファイル"sound.mp3"をロードして再生するには、つぎのようなフレームアクションを記述します(スクリプトTech02-001)。

スクリプトTech02-001■外部MP3サウンドファイルをロードして再生する

// フレームアクション
var _sound:Sound = new Sound();
var myRequest:URLRequest = new URLRequest("sound.mp3");
_sound.load(myRequest);
var myChannel:SoundChannel = _sound.play();

ひとつつけ加えておくのは、Sound.play()メソッドがSoundChannelインスタンスを返すことです。SoundChannelインスタンスは、再生したサウンドの停止やボリュームなどのコントロールに必要とされます。ですから、とくに不要な場合を除いて、変数に受取っておくよう心がけておくとよいでしょう。

Tips Tech02-001■相対URLの基準はHTMLドキュメント
URLRequestクラスのコンストラクタに指定する相対URLの基準は、デフォルトではSWFを埋込んだHTMLドキュメントになります。SWFファイルが基準ではありませんので、ご注意ください。これは、SWFファイルをHTMLドキュメントと別のフォルダに入れた場合に、とくに問題になります。

たとえば、上記スクリプトTech02-001を記述したSWFファイル(movie.swf)が、それを埋込んだHTMLドキュメント(main.html)と同階層のフォルダ(assets)内に納められたとします(図Tech02-001)。MP3サウンドファイル(sound.mp3)をSWF(およびFLA)ファイルと同じフォルダ内に置けば、[ムービープレビュー]やSWF単体で試すとサウンドが再生されます。しかし、HTMLドキュメントをブラウザで開いたとき、音が鳴らないという結果になります。

図Tech02-001■相対URLはSWFが埋込まれたHTMLドキュメントを基準に指定する

MP3ファイル(sound.mp3)はSWFファイル(movie.swf)と同階層でも、HTMLドキュメント(main.html)から見ればサブフォルダ(assets)内にある。

上図Tech02-001のファイル構成の場合、HTMLドキュメントから見た相対パスでMP3ファイルを指定しますので、前掲フレームアクション(スクリプトTech02-001)でURLRequestクラスのコンストラクタにはURLをつぎのように渡す必要があります。

assets/sound.mp3

[*筆者用参考]「<base>要素 - 相対URLの基準となるURLの指定」。


Tips Tech02-002■Soundコンストラクタの第1引数
Soundクラスのコンストラクタメソッドには、オプションの引数があります。第1引数にURLRequestインスタンスを渡すと、Soundインスタンス生成後、そのURLに対してSound.load()メソッドを自動的に呼出します。したがって、前掲スクリプトTech02-001で、もしURLRequestインスタンスを変数に保持する必要がなければ、最初の3行のステートメントをつぎの1行で済ませることができます。

var _sound:Sound = new Sound(new URLRequest("sound.mp3"));

Tips Tech02-003■サウンドの停止
サウンドを止めるには、そのサウンドを再生しているSoundChannelインスタンスに対して、SoundChannel.stop()メソッドを呼出します。前掲スクリプトTech02-001では、SoundChannelインスタンスを変数myChannelに設定しました。したがって、そのあと同じタイムラインのフレームアクションで再生を止めるには、つぎのステートメントを記述します。

myChannel.stop();

02-02 外部JPEG画像をロードして配置する
外部保存したJPEGやPNG、GIF形式などの画像ファイルやSWFファイルを読込むには、Loaderクラスを用います。その基本的な手順は、Soundクラスでサウンドをロードする場合と同じです。ただし、これらの読込んだファイルをステージ上に配置するには、もちろん表示リストに加えなければなりません。

同じ階層(Tips Tech02-001「相対URLの基準はHTMLドキュメント」参照)にあるJPEGファイル"PenBitmap.jpg"をLoaderインスタンスに読込んで、タイムラインに配置するには、つぎのようなフレームアクションを記述します(スクリプトTech02-002)。

スクリプトTech02-002■外部JPEG画像ファイルをロードして配置する

// フレームアクション
var myLoader:Loader = new Loader();
var myRequest:URLRequest = new URLRequest("PenBitmap.jpg");
addChild(myLoader);
myLoader.load(myRequest);

外部JPEGファイルのロードがMP3サウンドの場合と異なるのは、SoundでなくLoaderクラスを使うことと、タイムラインに配置するために表示リストに加える必要があること、あとはSound.play()のような追加のメソッドがないことくらいでしょう。基本的な手順は、ほとんど同じです。また、画像のがPNGやGIFであったり、あるいは外部SWFファイルを読込むときも、処理は変わりません。

問題は、ロードしたコンテンツに手を加えたい場合です。まず、位置座標を動かしたいときは、単純にLoaderインスタンスのDisplayObject.xDisplayObject.yプロパティで操作することができます(図Tech02-002)。しかし、読込んだコンテンツのサイズ、つまりDisplayObject.widthDisplayObject.heightプロパティには、コンテンツがロードし終わらないとアクセスできません。

図Tech02-002■Loaderインスタンスにロードした外部JPEGファイルをタイムラインに配置する

タイムラインに配置するコンテンツの位置を動かすには、LoaderインスタンスのDisplayObject.xDisplayObject.yプロパティを操作すればよい。

Loaderインスタンスがコンテンツを読込むと、そのコンテンツの最上位にあるDisplayObjectインスタンスの参照がLoader.contentプロパティに設定されます。したがって、その設定後でなければ、コンテンツのインスタンスを操作することができないのです。なお、コンテンツをロードする前のLoader.contentプロパティの値はnullです。

Maniac! Tech02-001■Loaderインスタンスの大きさの変更
読込まれるコンテンツでなく、LoaderインスタンスのDisplayObject.widthDisplayObject.heightプロパティも、操作することはできます。しかし、コンテンツのロード前に、これらのプロパティは設定すべきではありません。

コンテンツがなければ、LoaderインスタンスのDisplayObject.widthDisplayObject.heightプロパティの値はともに0です。0以外の値は設定できません。それどころか、プロパティに0以外の値を代入しようとすれば、0が設定されてしまうのです。

DisplayObject.widthDisplayObject.heightプロパティの値をとくに設定していなければ、読込まれたコンテンツの大きさでプロパティ値は自動的に更新されます。ところが、プロパティに一旦0が設定されていると、コンテンツをロードしてもその値は0のまま変わりません。つまり、コンテンツは表示されないことになります。

読込まれるコンテンツの大きさに関わりなく、Loaderインスタンスを一定の比率で拡大・縮小しておきたい場合には、DisplayObject.scaleXDisplayObject.scaleYプロパティであれば、コンテンツのロード前でも問題なく設定することができます。

それでは、コンテンツのロードを待つイベントリスナーを作成しましょう。ここで注意は、イベントリスナーを登録するターゲットのインスタンスです。それは、Loaderインスタンスではありません。

コンテンツのロードについての情報は、DisplayObjectクラスとは別のLoaderInfoクラスが管理します。Loaderインスタンスに読込まれるコンテンツの情報をもつLoaderInfoインスタンスは、LoaderインスタンスのLoader.contentLoaderInfoプロパティで参照できます。LoaderInfoインスタンスのLoaderInfo.completeイベントにリスナーを登録すれば、コンテンツを正しく読込み終わったときに処理が行われます。

LoaderインスタンスのLoader.contentLoaderInfoプロパティから得たLoaderInfoインスタンスの参照に対して、LoaderInfo.completeイベント(定数Event.COMPLETE)にリスナー関数を登録するフレームアクションは、以下のスクリプトTech02-003のとおりです。リスナー関数は、Loader.contentプロパティで取得したコンテンツのインスタンスに対して、DisplayObject.withプロパティの変更を行っています。

スクリプトTech02-003■ロードした外部JPEG画像ファイルのサイズを変えて配置する

// フレームアクション
var myLoader:Loader = new Loader();
var myRequest:URLRequest = new URLRequest("PenBitmap.jpg");
var myInfo:LoaderInfo = myLoader.contentLoaderInfo;
myInfo.addEventListener(Event.COMPLETE, xSetContent);
addChild(myLoader);
myLoader.load(myRequest);
trace(myLoader.content);   // 出力: null
function xSetContent(eventObject:Event):void {
  var myContent:DisplayObject = myLoader.content;
  trace(myContent);   // 出力: [object Bitmap]
  myContent.width = stage.stageWidth;
}

確認のため、Loader.load()メソッドの呼出し直後と、リスナー関数の本体内で、それぞれLoader.contentプロパティの値をtrace()関数で[出力]しています。[ムービープレビュー]で確かめると、前者はまだコンテンツが読込まれていないのでnullが[出力]され、後者ではビットマップがロードされたのでBitmapインスタンスであることを示す[出力]が表示ます。読込まれた外部JPEGファイルは、リスナー関数により幅が変更されています(図Tech02-003)。

図Tech02-003■Loader.contentLoaderInfoに登録したイベントリスナーでコンテンツのロードを待つ

trace()関数で[出力]したLoader.contentプロパティの値は、読込む前はnullで、ロードが済むとそのインスタンスを示す内容([object Bitmap])が表示される。

[*イラスト候補●Tech02-001] ロード状況はLoaderInfoインスタンスに聞け。


Tips Tech02-004■ロード待ちにおけるイベントリスナーの登録と読込みの順序
前掲スクリプトTech02-003では、LoaderInfo.completeイベントにリスナーを登録してから、Loader.load()メソッドを呼出しています。外部データをロードするときには、一般にこの順序で処理することをお勧めします。

手にもっているものを誰かに投げて渡そうとするとき、まず「受取って」と声をかけてから放るでしょう。投げてから叫んだのでは、相手が振向いたときには、すでにものを顔面で受止めているおそれがあるからです。

外部ファイルを読込むときにも、ロードし始めてしまってから完了時の処理を設定したのでは、設定の済む前に読込み終えてしまう可能性があります。ですから、まずロードが済んだ場合の処理をリスナーに登録してから、データの読込みを始める方が確実です。


Maniac! Tech02-002■DisplayObject.loaderInfoプロパティ
すべてのDisplayObjectインスタンスは、自らの属するファイルのLoaderInfoインスタンスの参照をDisplayObject.loaderInfoプロパティとして備えています。LoaderインスタンスのLoader.contentLoaderInfoプロパティが参照するLoaderInfoインスタンスは、読込まれるコンテンツのDisplayObject.loaderInfoプロパティの参照と同一です。詳しくは、FumioNonaka.com「LoaderInfoクラス」(<http://www.fumiononaka.com/TechNotes/Flash/FN0807001.html>)をご参照ください。


02-03 外部テキストファイルをロードして表示する
外部テキストファイルを読込むためのクラスは、URLLoaderです。同階層にあるテキストファイル"test.txt"をロードする処理は、つぎのフレームアクションのようになります。もちろん、このままではテキストはURLLoaderインスタンスに読込まれるだけで、ステージ上には表示されません。

var myLoader:URLLoader = new URLLoader();
var myRequest:URLRequest = new URLRequest("test.txt");
myLoader.load(myRequest);

読込んだテキストをステージに表示するためには、ふたつ確認しておく必要があります。

第1は、URLLoaderインスタンスそのものは、DisplayObjectクラスを継承せず、どのようにしても表示リストに加える方法はないということです。つまり、ステージに表示するには別のインスタンス、具体的にはTextFieldインスタンスを配置し、そのテキストにURLLoaderインスタンスが読込んだ内容を設定しなければならないのです。

すると、データのロード待ちが求められます。そこで第2に、イベントリスナーを、どのインスタンスに登録すればよいかです。ロード完了のイベントは、URLLoaderインスタンスが配信します。URLLoaderクラスは自らが表示リストに加わる資格をもたない代わりに、データのロードについての情報をもち、イベントを配信する機能を備えているのです。

[*イラスト候補●Tech02-002] URLLoaderはステージには上がれないけど、データのロードとイベントを管理する。

Flashムービー(FLA)ファイルと同じ階層にある外部テキストファイル"test.txt"を読込み、ロードし終えたテキストを、ステージに配置したTextFieldインスタンスに設定するフレームアクションは、以下のスクリプトTech02-004のとおりです。ロードの完了を伝えるイベントはURLLoader.complete(定数Event.COMPLETE)で、インスタンスにロードされたテキストはURLLoader.dataプロパティに設定されます。

スクリプトTech02-004■ロードした外部ファイルのテキストをTextFieldインスタンスに設定する

// フレームアクション
var _txt:TextField = new TextField();
var myLoader:URLLoader = new URLLoader();
var myRequest:URLRequest = new URLRequest("test.txt");
addChild(_txt);
_txt.autoSize = TextFieldAutoSize.LEFT;
myLoader.addEventListener(Event.COMPLETE, xSetText);
myLoader.load(myRequest);
function xSetText(eventObject:Event):void {
  _txt.text = myLoader.data;
}

TextField.autoSizeプロパティに指定をすると、TextField.textプロパティに設定されたテキストが表示しきれないとき、インスタンスのサイズを自動的に拡げることができます。その指定には、TextFieldAutoSizeクラスの定数を用います。TextFieldAutoSize.LEFTでは、TextFieldインスタンスの左上隅を固定してサイズが変更されます。

[ムービープレビュー]で結果を見ると、読込んだ外部ファイルのテキストが、ステージ左上隅に表示されます(図Tech02-004)。

図Tech02-004■URLLoaderインスタンスで読込んだテキストをロード後TextFieldインスタンスに設定
URLLoader.complete(定数Event.COMPLETE)イベントに登録したリスナー関数で、TextFieldインスタンスにURLLoader.dataプロパティのテキストを設定(左図)。外部テキストファイルは同階層に、UTF-8形式で保存する(右図)。

Tips Tech02-005■2バイト文字を含むテキストファイルはUTF-8で保存する
日本語などの2バイト文字を含むテキストファイルは、エンコーディングと呼ばれる文字コードの指定をUTF-8形式にして保存することをお勧めします。詳しくは、[ヘルプ]の[Flashユーザーガイド] > [多言語テキストの作成] > [多言語テキストとActionScript]をお読みください。

外部ファイルがXML形式の場合も、その実質はテキストです。したがって、ロードするまでの処理は、単純なテキストファイルと変わりません。違うのは、読込んだテキストを、XMLとして解析して処理することです。テキストをXMLとして扱うこと自体は、とても簡単です。その文字列をXML()関数またはXMLクラスのコンストラクタに引数として渡せばよいのです。XML()関数は、引数に渡されたオブジェクトを、XMLインスタンスに変換します。

同階層にある外部XMLファイル"test.xml"を読込んで、データをXMLとして解析したうえで値を取出し、TextFieldインスタンスに設定するフレームアクションは、以下のスクリプトTech02-005のとおりです。なお、XMLファイルの内容は、つぎのようなものだとします。

<cs3>
  <product suite="Web">
    <name>Flash</name>
    <price>699</price>
  </product>
  <product suite="Web">
    <name>Dreamweaver</name>
    <price>399</price>
  </product>
  <product suite="Design">
    <name>Photoshop</name>
    <price>649</price>
  </product>
  <product suite="Design">
    <name>Illustrator</name>
    <price>599</price>
  </product>
</cs3>
スクリプトTech02-005■ロードした外部XMLファイルから値を取出してTextFieldインスタンスに設定する

// フレームアクション
var my_xml:XML;
var _txt:TextField = new TextField();
var myLoader:URLLoader = new URLLoader();
var myRequest:URLRequest = new URLRequest("test.xml");
addChild(_txt);
_txt.autoSize = TextFieldAutoSize.LEFT;
myLoader.addEventListener(Event.COMPLETE, xSetText);
myLoader.load(myRequest);
function xSetText(eventObject:Event):void {
  my_xml = XML(myLoader.data);
  _txt.text = my_xml.product.name[0].toString();
}

上記スクリプトTech02-005のリスナー関数xSetText()は、URLLoader.dataプロパティで取得した文字列を、XML()関数の引数に渡すことにより、XMLデータに変換しています。XMLのデータは、構造化されたノードで構成されています。TextField.textプロパティに文字列を代入するステートメントの右辺は、XMLデータのproductノード群からname子ノード群を取出し、その最初のノード(インデックス0)に対してXML.toString()メソッドを呼出して文字列"Flash"を取得しています。XMLデータの扱い方は、次章Tech 03「ECMAScript for XMLと正規表現」で改めて説明します。

[ムービープレビュー]で確かめると、TextFieldインスタンスにはXMLデータから取出した文字列"Flash"が入力されます(図Tech02-005)。

図Tech02-005■ロードした外部ファイルの内容をXML()関数でXMLデータに変換して処理

XMLデータのproductノード群からname子ノード群を取出す。その最初のノードを文字列に変換して、TextFieldインスタンスのテキストに設定。

[Prev/Next]


作成者: 野中文雄
作成日: 2008年7月14日


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