Archive : 2008 年 8 月

8 月 23 2008

PV3Dでレースゲーム制作 12 - 3Dモデル読み込み編

Posted by tanjo at 8:41 PM

以前、SWFに埋め込んだ3DモデルをPapervision3Dで使用する方法を紹介しましたが、実は、ローダで読み込んでから描画するのも同じようなやり方でできます。
ゲーム的にも外部からロードした方が勝手が良さそうだし、今後はこっちを採用する方向でいきます。

*PV3DでCOLLADAを表示できた状態を基準に書いてます。COLLADAを表示方法はこちら
*以下、共通部分は以前の記事のコピペです。

それでは、手順を追っていきましょう。(ところどころ用語が間違ってたらすいません…。)
Papervision3D のマテリアルリストを使うので、まずはクラスをインポート。

import org.papervision3d.materials.utils.MaterialsList;

3DモデルのDAEファイルとテクスチャ画像を読み込み、それぞれ XML と Bitmap にインスタンス化しておきます。
参照:PV3Dでレースゲーム制作 11 - AS3で複数のファイルをロードする
↓↓インスタンス作成部分の抜粋。(宣言は割愛してます。)

courseXML = XML(loaderArray[0].data);
txMainBitmap = Bitmap(loaderArray[1].content);
txTreeBitmap = Bitmap(loaderArray[2].content);
txItemBitmap = Bitmap(loaderArray[3].content);

次にマテリアルの作成。

var mdCourse01Materials:Object = new Object();
mdCourse01Materials = {
	t_all_jpg:new BitmapMaterial(txMainBitmap.bitmapData),
	t_all_jpg_2:new BitmapMaterial(txMainBitmap.bitmapData),
	t_tree_png:new BitmapMaterial(txTreeBitmap.bitmapData),
	t_item_jpg:new BitmapMaterial(txItemBitmap.bitmapData)
};

テクスチャの Bitmap を元に、マテリアル用の Object へ BitmapMaterial を登録していきます。
ここで注意点!Object のキーは、COLLADAのマテリアル名を使います。(赤文字部分。記述は順不同でOK。)
ですので、もしマテリアル名に妙な記号とか2バイト文字とかが入ってる場合は、あらかじめCOLLADAを修正しておかなければなりません。
マテリアル名は、Blender(COLLADAインポート)ではアニメーションビュー、球体アイコンで確認できます。

COLLADAのXML内では material タグに定義されています。

<library_materials>
	<material id="t_all_jpg" name="t_all_jpg">
...

ただしここ以外の場所からもid名を参照していたりするので、手作業で名前を変更するときは、検索してそれらを一括で変えてあげないとダメかもしれません。

さてASに戻り、最後に3Dオブジェクト作成。

courseObjects = new Collada( courseXML, new MaterialsList(mdCourse01Materials) );

Collada() メソッドの第1引数に読み込んだ XML インスタンス、第2引数に先ほどの Object から作った MaterialsList を指定すればOK。

あとはいつもどおり、Collada を Scene3D に addChild して、renderScene で描画するだけ。(→参照
今回もゲーム的には進展なしなので、デモとかはありません…!

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モデルをプリロードしてから描画、というのが実装できそうです。

8 月 14 2008

PV3Dでレースゲーム制作 10 - 3Dモデル埋め込み編

Posted by tanjo at 11:14 PM

今までは何も考えずCollada生成のタイミングでDAEファイルにアクセスしていましたが(下記ソース)、これだと描画までに妙なタイムラグができてしまい、ウェブ公開向きの状態ではありませんね。

//3Dモデル作成
courseObjects = new Collada("assets/md_course01.dae");

対処としては、モデルデータ自体をSWFに埋め込む方法と、モデルデータのローディングイベントを用意する方法の2つがあると思います。
今回はモデルデータ一式をSWFに埋め込む方法について。「一式」と書いたのは、DAE本体だけでなく、DAEが指定しているテクスチャの画像ファイルも一緒に埋め込む必要があるからです。

参考にしたサイト

それでは、手順を追っていきましょう。(ところどころ用語が間違ってたらすいません…。)
Papervision3D のマテリアルリストを使うので、まずはクラスをインポート。

import org.papervision3d.materials.utils.MaterialsList;

コンストラクタの前にCOLLADAとテクスチャを Embed しておきます。

[Embed(source = "embed/md_course01.dae", mimeType = "application/octet-stream")]
private var mdCourse01:Class;

[Embed(source = "embed/tx_main.jpg")]
private var txMain:Class;

[Embed(source = "embed/tx_tree.png")]
private var txTree:Class;

[Embed(source = "embed/tx_item.jpg")]
private var txItem:Class;

このようにテクスチャ画像が複数あるときは、すべて Embed しておく必要があります。
ちなみに Loader とかで読み込むファイルはSWFのパスが基準、一方 Embed はソースの場所が基準になります。作業ディレクトリを分けてるときは要注意です。

次にマテリアルの作成。

var txMainBitmap:Bitmap = new txMain() as Bitmap;
var txTreeBitmap:Bitmap = new txTree() as Bitmap;
var txItemBitmap:Bitmap = new txItem() as Bitmap;
var mdCourse01Materials:Object = new Object();
mdCourse01Materials = {
	t_all_jpg:new BitmapMaterial(txMainBitmap.bitmapData),
	t_all_jpg_2:new BitmapMaterial(txMainBitmap.bitmapData),
	t_tree_png:new BitmapMaterial(txTreeBitmap.bitmapData),
	t_item_jpg:new BitmapMaterial(txItemBitmap.bitmapData)
};

Embed 時に作成したクラスから、Bitmap インスタンスを作成します。そしてこれらを元に、マテリアル用の Object に BitmapMaterial を登録していきます。
ここで注意点!Object のキーは、COLLADAのマテリアル名を使います。(赤文字部分。記述は順不同でOK。)
ですので、もしマテリアル名に妙な記号とか2バイト文字とかが入ってる場合は、あらかじめCOLLADAを修正しておかなければなりません。
マテリアル名は、Blender(COLLADAインポート)ではアニメーションビュー、球体アイコンで確認できます。

COLLADAのXML内では material タグに定義されています。

<library_materials>
	<material id="t_all_jpg" name="t_all_jpg">
...

ただしここ以外の場所からもid名を参照していたりするので、手作業で名前を変更するときは、検索してそれらを一括で変えてあげないとダメかもしれません。

さてASに戻り、最後に3Dオブジェクト作成。記事冒頭のソース部分の置き換えです。

courseObjects = new Collada( XML(new mdCourse01()), new MaterialsList(mdCourse01Materials) );

Collada() メソッドの第1引数にモデルクラスのインスタンスを XML にキャストしたもの、第2引数に先ほどの Object から作った MaterialsList を指定すればOK。Collada() に直接DAEファイルを指定したときと同じ物が生成されるはずです。

あとはいつもどおり、Collada を Scene3D に addChild して、renderScene で描画するだけ。(→参照
今回はゲーム的には進展なしなので、デモとかはありません…!

8 月 04 2008

Papervision3Dでレースゲーム制作 09 - コンセプトバージョン完成

Posted by tanjo at 3:48 AM

仮題「PV3D Racing “Concept-α”」が完成しました!

PV3D Racing “Concept-α”

レースゲーム・デモ画面

ゲームをプレイする (要:Flash Player 9.0.115.0以降 / 読み込むのに少し時間がかかります)

まだ遊ぶための要素がないし、ローディングすら実装されていない状態ですが、でも、とりあえず ActionScript 3.0 + Papervision3D でこんな感じのレースゲームが作れますよ、っていうのが伝わるレベルにはなったと思います。

ダウンロード版

ダウンロード版の方が若干軽く動作します。またフルスクリーンモードにも対応しています。内容は同じです。

ダウンロードする (2.0MB)

ダウンロード版をプレイするには、Flash Player 9 (standalone) が必要です。スタンドアロン版の Flash Player は、Adobe Flash Player - Downloads のページにて無償で配布されています。 (ページ内、Flash Player 9 Projector というリンクです。)

メイキング

このゲームの制作に使ったソフトウェアとライブラリ。

*このゲームのソースファイル Main.as はこちらから参照できます。

レースゲーム制作記(当ブログ内)