クラスまみれのゲームプログラミング入門

第2回:プレイヤーを移動させる

 プレイヤーキャラクターに動きを持たせましょう。まずはCPlayerクラスにprivate属性としてCInput*を追加します。

Player.h
class CPlayer : public CCharactor
{
	/* 省略 */
private:
	CInput *input;
};

 続いてInit()でCInputへの関連づけを行います。FindObject()で入力クラスが見つからないときは、新規にCInputクラスを作成し、タスクリストに追加するようにしています。

Player_init.cpp
void CPlayer::Init()
{
	input = (CInput*)FindObject("input");
	if(input == NULL){
		input = new CInput();
		AppendObject(input, 0, "input", true);
	}

	x = 320.0f;
	y = 400.0f;
}

 ループ処理時ではExec()が呼び出されるので、この中で、入力されたキーに基づく処理を記述します。

Player_exec.cpp
void CPlayer::Exec()
{
	const float move_s = 4.0f;
	const float move_a = move_s / sqrtf(2.0f);

	BYTE ppos = input->GetPovPosition();

	BOOL left = input->IsKeyDown(DIK_LEFT);
	left |= (ppos & PP_LEFT) ? TRUE : FALSE ;
	BOOL right = input->IsKeyDown(DIK_RIGHT);
	right |= (ppos & PP_RIGHT) ? TRUE : FALSE ;
	BOOL up = input->IsKeyDown(DIK_UP);
	up |= (ppos & PP_UP) ? TRUE : FALSE ;
	BOOL down = input->IsKeyDown(DIK_DOWN);
	down |= (ppos & PP_DOWN) ? TRUE : FALSE ;

	if(up & left){
		x -= move_a;
		y -= move_a;
	}else if(up & right){
		x += move_a;
		y -= move_a;
	}else if(down & left){
		x -= move_a;
		y += move_a;
	}else if(down & right){
		x += move_a;
		y += move_a;
	}else if(up){
		y -= move_s;
	}else if(down){
		y += move_s;
	}else if(left){
		x -= move_s;
	}else if(right){
		x += move_s;
	}

	if(x < 32.0f) x = 32.0f;
	else if(x > 640.0f - 32.0f) x = 640.0f - 32.0f;

	if(y < 32.0f) y = 32.0f;
	else if(y > 480.0f - 32.0f) y = 480.0f - 32.0f;

	if(left){
		sprite.SetFrame(2);
	}else if(right){
		sprite.SetFrame(1);
	}else{
		sprite.SetFrame(0);
	}

	sprite.Draw(x, y);
}

 はじめの2行では1フレーム当たりのプレイヤーの移動量を定義しています。ただし、斜め移動も同じ移動量にすると、斜め方向の移動スピードが垂直・水平方向に比べやや早くなってしまうため、水平移動量から√2で割ることで、斜め移動のスピードと水平移動のスピードを合わせています。

 次にゲームパッドとキーボードでの十字方向入力を取得し、それをもとに、x方向とy方向の移動先を決定し、移動後の座標が画面からはみ出すようであれば、修正します。また、sprite.SetFrame()では、方向キーの左右入力に合わせて、機体を左右に傾けているグラフィックを表示するようにしています。

 コンパイル・実行を行うと、キーパッドやキーボードよりプレイヤーの移動が行えるようになります。