10 月 06 2008

PV3Dでレースゲーム制作 19 - リプレイ用カメラの設置

Posted by tanjo at 4:31 PM

今度の目標はリプレイモードの搭載。
まずは、TV中継のように車を追ってくれる固定カメラを設置していきます。

この辺は、私と同じく Papervision3D でレースゲームを作っているかたの記事がとても参考になりました。ほとんど同じやり方で実装してみます。
» CgInstitute Flash コミュニティー belcro - blog | d5 さんのブログ

処理の流れはこんな感じです。しかも2Dです。

  1. 配列に各カメラの座標を登録。
  2. 車の位置から最も近い座標を割り出す。
  3. その座標にカメラを移動し、車の方を向かせる。

これで車がどんな走り方をしようが、それなりに上手く追っかけてくれます。もちろんカメラの設置場所は結構吟味しましたけど。

カメラ座標の登録

配列の中に座標を示した連想配列を入れていきます。

cameraList = new Array();
cameraList[0] = new Object();
cameraList[0] = {
	x:1200,
	y:300
};

ま、手作業だと面倒くさいので、実際は例のごとく配列作成用画像を使って自動化させます。赤がFFの点を調べて push() で配列を作っていきました。

dt_course01
*赤い点が見えない。。。クリックすると拡大表示します。

最も近い点を割り出す

車の位置から1番近いカメラ座標を求めます。
候補が20個程度なら総当たりで調べてもそんなに問題なかろう…というわけで、1つずつ距離を調べて最短を割り出しています。2点間の距離(というかその2乗)を求めるために簡単な関数を作りました。

private function targetDistance2(x1:Number = 0, y1:Number = 0, x2:Number = 0, y2:Number = 0):Number
{
	var distance:Number;
	var dx:Number = x2 - x1;
	var dy:Number = y2 - y1;
	distance = dx * dx + dy * dy;
	return distance;
}

カメラをセット

リプレイ用カメラと言っても、普段使っているドライバーズ・ビューのカメラを移動させて使い回しているだけです。上で求めた座標にカメラを移動させ、そこから車が中心になるようにカメラを回転させます。今度は2点から向きを計算する関数が必要ですね。

private function targetDirection(x1:Number = 0, y1:Number = 0, x2:Number = 0, y2:Number = 0):Number
{
	var direction:Number;		//RADIAN
	var dx:Number = x2 - x1;
	var dy:Number = y2 - y1;
	direction = Math.atan2(dy, dx);			// -π ~ π
	if (direction < 0) direction += 2 * Math.PI;	// 0 ~ 2π
	return direction;
}

角度を求めるには、タンジェントの逆関数アークタンジェントを使います。
アークタンジェント?Δy=0だったときとか、対角象限の場合分けが面倒くさ~と思いきや、ActionScript 3 には Math.atan(val) のほかに、Math.atan2(y,x) ってのがあるんですね…!atan2 なら座標がどんな値でも一発で360度しっかり求めてくれます。これは便利。

ちなみに、このゲームでは疑似3Dや2Dを多用しているせいで、カメラは水平にしか振ることができません。でも意外とそれっぽい見え方にはなってくれている、はず!

デモ

レースゲームデモ画面

» ゲームをプレイする (要:Flash Player 9.0.115.0以降)

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

プレイ中に [C] キーを押すとカメラモードが切り替わります。
(今までこんな直方体の車に乗っていたと!?)

Leave a Reply