7 月 07 2008

Papervision3Dでレースゲーム制作 02 - コース床の作成

Posted by tanjo at 5:19 AM

レースゲーム・サンプル画面

今回はコースの床を作成します。
固定のPlane1枚をまず作り、自機の位置情報から割り出したテクスチャを毎フレームそこに貼り付ける、という方法で擬似的にコースを表現します。

床となるPlaneの生成。

private function init3D():void
{
	//ビューポート設定
	viewport = new Viewport3D(0,0,true);
	addChild(viewport);

	//レンダー設定
	renderer = new BasicRenderEngine();

	//カメラ設定
	camera = new FreeCamera3D();
	camera.y = 206;
	camera.z = -2002;
	camera.rotationX = 0;
	camera.focus = 420;
	camera.zoom = 1;

	//シーン設定
	scene = new Scene3D();

	//フィールド生成
	fieldBitmap = new Bitmap();
	fieldBitmap.bitmapData = new courseSample(0, 0);
	floorBitmapData = new BitmapData(400, 300, false, 0x666666);
	//ビットマップデータの取得
	floorBitmapData = getFloorBitmapData(myPositionX, myPositionY, myDirection);

	//マテリアル設定
	floorPreciseMaterial = new BitmapMaterial(floorBitmapData, true);

	//Plane生成
	var segmentW:Number = 1;
	var segmentH:Number = 1;
	floorPlane = new Plane(floorPreciseMaterial, 8000, 6000, segmentW, segmentH);
	floorPlane.rotationX = -90;
	floorPlane.z = 1000;

	//描画登録
	scene.addChild(floorPlane);
}

getFloorBitmapData メソッドで取得した BitmapData をテクスチャと使用しています。
Planeを作成する際、暫定的に、BitmapMaterial() の第2引数 precise を true にして、テクスチャのパース変形ができるマテリアルにしています。precise を false にした方が高速ですが、segment を微調整して歪みを軽減してやる必要が出てきます。(面倒くさいッ。)

BitmapData の取得について。
自機の位置座標と向きをもとに、床に描画すべき範囲を全景画像 fieldBitmap からトリミングするメソッドです。
○○を中心に回転させる、っていう方法が分からなかった(というか無い?)ので、原点中心で回転させてから移動してます。移動距離は座標の回転変換の式から逆算してます。
んん~。数学は苦手ですね。

private function getFloorBitmapData(x:Number, y:Number, th:Number):BitmapData
{
	var returnBitmapData:BitmapData = new BitmapData(400, 300, false, 0x84c35b);
	var trimRectangle:Rectangle = new Rectangle(0, 0, 400, 300);
	var trimMatrix:Matrix = new Matrix();
	var rotateRadian:Number;
	var translateX:Number;
	var translateY:Number;

	//座標の回転移動
	rotateRadian = -(th - (-Math.PI/2));	// -π/2の向き(上)を基準にする
	translateX = x * Math.cos(rotateRadian) - y * Math.sin(rotateRadian);
	translateY = y * Math.cos(rotateRadian) + x * Math.sin(rotateRadian);

	trimMatrix.rotate(rotateRadian);
	trimMatrix.translate(-(translateX - floorWidth/2), -(translateY + 5 - floorHeight));

	returnBitmapData.draw(fieldBitmap, trimMatrix, null, null, trimRectangle);
	return returnBitmapData;
}

そして最後に。
自機の位置情報更新 → BitmapData を再取得 → マテリアルをアップデート → レンダリング、という手順を毎フレーム繰り返して、車がコース上を走ってるっぽい表現にしています。
updateBitmap() をしないと変更が反映されないので注意。

floorBitmapData = getFloorBitmapData(myPositionX, myPositionY, myDirection);
floorPreciseMaterial.bitmap = floorBitmapData;
floorPreciseMaterial.updateBitmap();

renderer.renderScene(scene, camera, viewport);

こういうものができあがりました
走ってないけど走ってるっぽい感じはするでしょうか。ちなみに車の挙動とかはテキトーです(^^;

*ソースファイル Main.as の全文はこちらから参照できます。
(試行錯誤中のソースなんで怪しい行がいっぱいありますが、気にしないでくださいね~。)

Leave a Reply