8 月 23 2008

PV3Dでレースゲーム制作 11 - AS3で複数のファイルをロードする

Posted by tanjo at 7:30 PM

Loader クラス、URLLoader クラスを使って、複数の画像やテキストを読み込みます。
たぶんこの辺は上手いやり方ってのがあるんでしょうかね~。でもなかなかピッタリなのが見つからなかったので、適当に作ってみました。といってもまだちゃんとしたクラスにはしていません。ただの function です。。

参考サイト
AS3:16.外部画像をまとめて読み込むクラス

気をつけた点とか。
複数のファイルを同時にロードしようとするとトラブルが起きやすいっぽいです。なので、1つ読み終えてから次のファイルに移るようにしています。
あとは個人的な都合です。使うファイルは多くても10個くらいだからファイル登録とインスタンス化は手作業でも問題なし。それ以外は自動化。読み込むファイルはとりあえず画像とXML(COLLADA)。

以下の例では、DAEファイルとテクスチャの画像3つを読み込み、(あらかじめ宣言してある)courseXML:XML、txMainBitmap:Bitmap、txTreeBitmap:Bitmap、txItemBitmap:Bitmap に割り当てています。

private function loadStart():void
{
	//読み込むファイルの登録
	var loadContent:Array = new Array();
	loadContent.push("assets/md_course01.dae");
	loadContent.push("assets/tx_main.jpg");
	loadContent.push("assets/tx_tree.png");
	loadContent.push("assets/tx_item.jpg");
	var loadFilesNumber:int = loadContent.length;	//ファイル数

	//すべて完了したときの処理
	function loadComplete():void
	{
		//インスタンスの生成
		courseXML = XML(loaderArray.shift().data);
		txMainBitmap = Bitmap(loaderArray.shift().content);
		txTreeBitmap = Bitmap(loaderArray.shift().content);
		txItemBitmap = Bitmap(loaderArray.shift().content);

		//ゲームへ
		initialize();
	}

	//以上で登録完了
	//--------------------------------//

	//拡張子の判定
	var patternIMG:RegExp = /\.(jpe?g|gif|png)$/i;
	var patternXML:RegExp = /\.(dae|xml)$/i;

	//進捗カウント
	var loadCount:int = 0;
	var loadedRate:Number = 0;

	//ローダ作成
	var loaderArray:Array = new Array();
	for (var i:int = 0; i < loadFilesNumber; i++)
	{
		if (patternIMG.test(loadContent[i]))
		{
			loaderArray[i] = new Loader();
			loaderArray[i].contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loaderProgressHandler);
			loaderArray[i].contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleteHandler);
			loaderArray[i].contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loaderErrorHandler);
		}
		else if (patternXML.test(loadContent[i]))
		{
			loaderArray[i] = new URLLoader();
			loaderArray[i].addEventListener(ProgressEvent.PROGRESS, loaderProgressHandler);
			loaderArray[i].addEventListener(Event.COMPLETE, loaderCompleteHandler);
			loaderArray[i].addEventListener(IOErrorEvent.IO_ERROR, loaderErrorHandler);
		}
	}

	//最初のファイルを読み込み開始
	var request:URLRequest = new URLRequest(loadContent[loadCount]);
	loaderArray[loadCount].load(request);

	//読み込み中
	function loaderProgressHandler(event:ProgressEvent):void
	{
		loadedRate = ((event.bytesLoaded / event.bytesTotal) + loadCount) / loadFilesNumber;
		trace(Math.floor(loadedRate * 100) + "%");
	}

	//読み込み完了
	function loaderCompleteHandler(event:Event):void
	{
		loadCount++;

		//すべて完了
		if (loadCount == loadFilesNumber)
		{
			loadComplete();
		}
		//次のファイルを読み込む
		else
		{
			request = new URLRequest(loadContent[loadCount]);
			loaderArray[loadCount].load(request);
		}
	}

	//読み込み失敗
	function loaderErrorHandler(event:IOErrorEvent):void
	{
		trace(loadContent[loadCount]+" の読み込みに失敗しました。");
	}
}

ローダ作成→ イベント登録 → 1つ目をロード開始 → 完了したら次をロード → すべてロードしたらインスタンス化、という流れです。実行すると全体の進捗(%)がトレースされます。

ローダには配列を使っています。使い回していないからこれならローダ作成時に全ファイルの合計容量とか求められる!…と思いきや、「bytesTotal は初期値ゼロ、最初の progress イベントが送出された後反映される」ということでダメでした。読み込みを開始しないと取得できないようです。(ま、当然か。)
そういうわけなんで、全体の進捗も合計バイト数ではなく、読み込むファイル数をもとにしています。(4ファイル中1つ目を読み終えると25%、というふうに。)

あと厄介だったのは、画像とXMLとでローダのクラスが Loader / URLLoader と違ったり、contentLoaderInfo を使うか使わないかという仕様の違いがあること。そのため拡張子を判定して処理を分けています。
ちなみにこの例では使用していませんが、SWF は画像と同じように、テキストファイルは XML と同様に扱うことができます。ローディングイベントについて詳しいことはFlashゲームPG講座 For AS3.0【ファイルの読み込みについて】をどうぞ。

さて、何はともあれ、これでDAEファイルを XML のインスタンスとして読み込むことができました。前回の埋め込みCollada作成法と組み合わせれば、外部3Dモデルをプリロードしてから描画、というのが実装できそうです。

One Response to “PV3Dでレースゲーム制作 11 - AS3で複数のファイルをロードする”

  1. [...] これと同じケースではないと思いますが、こちら でも [...]

Leave a Reply