スクロール方向によらない移動

 何となく、沙羅曼蛇みたいな感じのゲームを作ろうとしたとき、

3D座標準拠で作ろうとすると、少し困ったことが起こります。



 いろいろとあると思うけど、とりあえずパッとサイデリア思い浮かんだのは、

自機の移動方向と入力方向の対応関係ですか。



 まぁ、行列変換でいいんじゃない?と言われればそれまでなんですが。



 具体的にどういうことかというと、


※以下、入力方向→ゲーム内移動方向

・横スクロール時
 xy → xy
・縦スクロール時
 xy → zx

!移動させたい方向と入力させたい方向の軸が一致していない。

こんな感じで、スクロール方向によって移動させたい方向が別物なわけです。

しかも奥の方向にひねるような感じで方向が違うので、単純な三角関数の演算で誤魔化すことも出来なさそう…。

(極論、フラグ持たせておいて合わせて動かせばいいんだけど、今回は条件分岐なしでの移動を目的とします。)



 というわけで、何とか行列演算で出来ないかと言う話。

結果から述べると、ビルボードの応用で出来ます。

ビルボードはカメラに対して必ず一定の面を平行に見せているわけですから、

このときの行列に入力分を移動量として与えればいいんじゃないかと。



 で、具体例。

/*=====================================
 x,  y,  z : 入力方向
rx, ry, rz : 実際の移動量
=====================================*/
void GetCamera_AxisTransrate( float x, float y, float z,
			float *rx, float *ry, float *rz )
{
	float dx = x,
		dy = y,
		dz = z;

	D3DXMATRIX out;
	// カメラ行列(透視変換とかビュー行列とか言うやつ)の逆行列取得
	D3DXMatrixInverse( &out, NULL, &g_camera );

	// 平行移動分をそのまま足すと
	// カメラの座標分 + xyzになってしまうので、加算しない
	(*rx) = out._11 *dx + out._21 *dy + out._31 *dz;// + out._41;
	(*ry) = out._12 *dx + out._22 *dy + out._32 *dz;// + out._42;
	(*rz) = out._13 *dx + out._23 *dy + out._33 *dz;// + out._43;
	return;
}

これで入力から移動量を取得すれば、



縦だろうと、



横だろうと、



縦だか横だかわからない方向だろうと、

十字キーの↑を入力すれば、画面上の↑へ移動してくれるようになります。





 行列の座標変換(アフィン変換)に関しては、↓辺りがきれいにまとまっていて読みやすいかも。

Visual C++ を使ってルービックキューブを作ってみよう

 行列がわからない場合は、地道に勉強しましょう(汗)

一応、↓がオススメ…というか、後から勉強する人間には定番らしい…。

空がとっても青いから