7 月 07 2008
Papervision3Dでレースゲーム制作 02 - コース床の作成
今回はコースの床を作成します。
固定の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 の全文はこちらから参照できます。
(試行錯誤中のソースなんで怪しい行がいっぱいありますが、気にしないでくださいね~。)
