オブジェクト指向を意識してC++でシューティングゲームを作る(4)

前回、「オブジェクト指向を意識してC++でシューティングゲームを作る(3)」で弾の発射の部分の所までやりました。
ですが、あのままでは一度に弾を確保できる個数が100発のため、今回は要らなくなった弾を削除する処理をやりたいと思います。


やること

  1. 前回のコードのバグ修正
  2. 要らなくなった弾の判定処理

前回のコードのバグ修正

まず最初に私も意図していなかったのですが。右と左又は上と下を同時押しすると左上に移動していくバグを発見したのでここで修正しておきます。

Dxライブラリでベクトルの長さの二乗を取得する関数VSquareSizeを使って長さが0場合は移動の処理をしないようにします。
Player.h

void CPlayer::Update()
{
	//移動する向き
	VECTOR vPos = VGet(0, 0, 0);
	//弾の発射を抑制するトリガー
	static int count = 0;
	//移動していないときは正規化する必要がないのでこれで移動しているか確認する
	bool moveFlag = false;
	if (manager->GetKey()[KEY_INPUT_LEFT] > 0)
	{
		vPos.x -= 1.0f;
		moveFlag = true;
	}
	if (manager->GetKey()[KEY_INPUT_RIGHT] > 0)
	{
		vPos.x += 1.0f;
		moveFlag = true;
	}
	if (manager->GetKey()[KEY_INPUT_UP] > 0)
	{
		vPos.y -= 1.0f;
		moveFlag = true;
	}
	if (manager->GetKey()[KEY_INPUT_DOWN] > 0)
	{
		vPos.y += 1.0f;
		moveFlag = true;
	}
	if (moveFlag && VSquareSize(vPos) != 0)//ここを修正
	{
		vPos = VNorm(vPos);
		vPos = VScale(vPos, PLAYER_SPEED);
		//現在の座標に移動量を加算する
		pos = VAdd(pos, vPos);
	}
	//弾の発射
	if (manager->GetKey()[KEY_INPUT_SPACE] > 0)
	{
		count++;
	}
	else
	{
		count = 0;
	}
	if ((count % 10) == 1)
	{
		//上に弾を飛ばす
		bulletManager->Shot(&bulletGraphic, pos, VGet(0, -7, 0));
	}
}

要らなくなった弾の判定処理

前回の弾の処理で最大100発打つと弾の配列がいっぱいになり、次の弾が出せない仕様にしていましたが、画面外に出ていらなくなった弾を削除することで、次の弾の入れる枠を確保できるようにします。


まず、弾が画面外にあるかどうかの確認のために生存フラグを作ります。
Bullet.h

#pragma once
//弾の管理
class CBullet:public CObject
{
	//進む方向ベクトル
	VECTOR vPos;
	//弾の生存フラグ(true = 生きている)
	bool flag;
public:
	CBullet(){};
	CBullet(int *tex, VECTOR &position, VECTOR &vPosition);
	~CBullet();
	//描画
	void Render();
	//更新
	void Update();
	//弾の生存フラグを取得
	bool GetFlag(){ return flag; };
};


画面外に出た処理をするために画面の大きさをDefine.hを作ってそこで定義します。

f:id:haina817:20161107152459p:plain

Define.hをBullet.cppの上で定義して、
生存フラグはコンストラクタでtrueにし、画面外に出たときにfalseにします。
画面外に出たか確認の処理はUpdate関数の最後に書きます。
Bullet.cpp

CBullet::CBullet(int *tex, VECTOR &position, VECTOR &vPosition)
{
	graphic = tex;
	pos = position;
	vPos = vPosition;
	flag = true;
}
void CBullet::Update()
{
	//最初にフラグを倒す
	flag = false;
	pos = VAdd(pos, vPos);
	//画面内にいるか確認
	if (pos.x < GAME_SCREEN_WIDTH && pos.x > 0)
	{

		if (pos.y < GAME_SCREEN_HEIGHT && pos.y > 0)
		{
			//画面内ならフラグを元に戻す
			flag = true;
		}

	}
}


これで画面外に出た弾はflagがfalseになります。
つまりflagがfalseになっている弾はもう使わない弾という事なので削除してしまいます。

BulletManager.cpp

void CBulletManager::Update()
{
	for (int num = 0; num < BULLET_NUM; num++)
	{
		//NULLでない場合
		if (bullet[num] != NULL)
		{
			bullet[num]->Update();
			//弾が画面外に出た場合
			if (bullet[num]->GetFlag() == false)
			{
				//削除してからNULLを入れる
				delete bullet[num];
				bullet[num] = NULL;
			}
		}
	}
}


これで弾を無限に出すことができるようになりました。
この先が少し長くなってしまうため、今回は一旦これで終わりにします。

次回は、敵の処理の部分を作って行きます。
次「オブジェクト指向を意識してC++でシューティングゲームを作る(5) - hainaのゲーム制作日記