2Dゲーム制作㉖(2025/10/13)


(SceneGame.cpp)

//状況を検知して返す
eStageExitConditionsKind GameScene::StageExitConditionCheck(void)
{
	eStageExitConditionsKind exitCondition = ESTAGE_EXIT_NON;

	//敵の残機数を取得する
	int enemyNum = en->GetEnemyRestNum();

	if (enemyNum == 0) {
		//敵の残機数が0なので、プレイヤーがステージをクリアした
		exitCondition = ESTAGE_EXIT_CLEAR;
	}
	else if (pl->GetAlive() == false) {
		//プレイヤーがやられた
		exitCondition = ESTAGE_EXIT_ENEMY_SHOT;
	}
	else if (en->CheckHitEdgeProc() == ENEMY_HIT_EDGE_DOWN) {
		//敵が最下段に到達した
		exitCondition = ESTAGE_EXIT_ENEMY_OCCUPATION;
	}
	return exitCondition;
}

ゲッター関数・セッター関数を準備。
(PlayerBullet.h)

#pragma once
#include"StDefine.h"

class SceneManager;
class Player;

class PlayerBullet
{
public:
	constexpr int PLAYER_BULLET_WID = 6;		// プレイヤー弾の画像の横サイズ
	constexpr int PLAYER_BULLET_HIG = 30;		// プレイヤー弾の画像の縦サイズ
	constexpr int PLAYER_BULLET_MOVE = 12;		// プレイヤー弾の移動速度
	constexpr int BOMB_MAX = 4;					// 押し戻しの最大回数

	PlayerBullet(SceneManager* scm, Player* pl); //Player型のインスタンスのポインタをうけられるように準備
	~PlayerBullet(void);

	bool SystemInit(void);
	void GameInit(void);
	void UpdateShot(void);
	void UpdateMove(void);
	void Draw(void);
	void Bomb(void);
	bool Release(void);

	POSITION GetPos(void) { return pos; }
	bool GetAlive(void) { return aliveFlg; }
	void SetAliveOff(void) { aliveFlg = false; }
	int GetPlayerStock(void) { return PlayerStock; }

private:
	SceneManager* scmInst;		//SceneManagerクラスのインスタンスのポインタ
	Player* pInst;				//Playerクラスのインスタンスのポインタ

	int img;				//プレイヤー弾の画像ハンドル番号
	POSITION pos;				//プレイヤー弾の座標
	bool aliveFlg;				//プレイヤー弾の存在フラグ(true:表示、false:非表示)
	int bombStock;				//ボム弾数
}

(Enemy.h)

#pragma once
#include "Stdefine.h"

class Enemy;
{

public:
	Enemy(void);
	~Enemy(void);

	bool SystemInit(void);
	void GameInit(void);
	void OccupationInit(void);
	void Update(void);
	void Draw(void);
	bool Release(void);

	eEnemyHitEdgeDir CheckHitEdgeProc(void);
	int GetEnemyRestNum(void);				//敵の残機数を取得

	bool GetAlive(int x, int y){ return flgArray[y][x]; }
	void SetAliveOff(int x, int y) { flgArray[y][x] = false; }
	POSITION GetPos(int x, int y) { return posArray[y][x]; }
	void SetPos(int x, int y, POSITION pos) { posArray[y][x] = pos; }
	eEnemyMoveDirection GetMoveDir(void) { return eMoveDirection; }
	eEnemyMoveDirection GetNextMoveDir(void) { return eNextMoveDirection; }
	void SetMoveDir(eEnemyMoveDirection dir) { eMoveDirection = dir; }
	void SetNextMoveDir(eEnemyMoveDirection dir) {eNextMoveDirection = dir;	}


	// 敵キャラ
	static constexpr int ENEMY_WID = 32;		// 敵の画像の横サイズ
	static constexpr int ENEMY_HIG = 23;		// 敵の画像の縦サイズ
	static constexpr int ENEMY_PATTERNS = 2;	//敵のアニメーション配列数
	static constexpr int ENEMY_DISP_X_DISTANCE = 8;	//敵キャラ同士の横の間隔
	static constexpr int ENEMY_DISP_Y_DISTANCE = 4;	//敵キャラ同士の縦の間隔

	// 敵キャラの画面表示関連
	static constexpr int ENEMY_DISP_XNUM = 8;	// 敵キャラの横の表示個数
	static constexpr int ENEMY_DISP_YNUM = 7;	// 敵キャラの縦の表示個数
	
	// 敵キャラの移動関連
	static constexpr int ENEMY_MOVE_X_SPEED = 4;	//敵の横方向の移動量
	static constexpr int ENEMY_MOVE_Y_SPEED = (ENEMY_HIG + ENEMY_DISP_Y_DISTANCE);//敵の縦方向移動量
	static constexpr int ENEMY_MOVE_INTERVAL_COUNT = 8;	//敵移動のインターバル



private:
	//敵キャラの表示関連
	static constexpr int ENEMY_DISP_ALL_NUM = ENEMY_DISP_XNUM * ENEMY_DISP_YNUM;

	// 敵キャラ
	int imageArray[ENEMY_PATTERNS];			// 敵の画像ハンドル番号
	POSITION posArray[ENEMY_DISP_YNUM][ENEMY_DISP_XNUM];// 敵のX座標表示位置テーブル
	bool flgArray[ENEMY_DISP_YNUM][ENEMY_DISP_XNUM];// 敵の存在フラグテーブル

	eEnemyMoveDirection eMoveDirection;		//敵キャラの現在の移動方向
	eEnemyMoveDirection eNextMoveDirection;	//敵キャラの下移動後の移動方向
	int eMoveIntervalCounter;		//敵キャラ移動の間隔調整用カウンタ

};

(EnemyBullet.h)

#pragma once

#include"Enemy.h"

class EnemyBullet
{
//-----------------------
// 定数定義
// -----------------------
	static constexpr int ENEMY_BULLET_MOVE = 3;	//敵弾の移動量
	static constexpr int ENEMY_BULLET_RAND_MAX = 99;
	static constexpr int ENEMY_BULLET_RAND_VALUE = 10;
public:
	static constexpr int ENEMY_BULLET_WID = 16;	//敵弾の画像幅
	static constexpr int ENEMY_BULLET_HIG = 25;	//敵弾の画像高さ

	EnemyBullet(Enemy* enemy);
	~EnemyBullet(void);

	bool SystemInit(void);
	bool GameInit(void);
	void UpdateShot(void);
	void UpdateMove(void);
	void Draw(void);
	bool Release(void);

	bool GetAlive(int, int y) { return flgArray[y][x]; }		//弾の座標取得
	void SetAliveOff(int x, int y) { flgArray[y][x] = false; }
	POSITION GetPos(int x, int y) { return posArray[y][x]; }
	void SetPos(int x, int y, POSITION pos) { posArray[y][x] = pos; }

private:
	Enemy* eInst;		//Enemyクラスのインスタンスのポインタ ※

	int img;
	POSITION posArray[ENEMY_DISP_YNUM][ENEMY_DISP_XNUM];
	bool flgArray[Enemy::ENEMY_DISP_YNUM][Enemy::ENEMY_DISP_XNUM];
};

(Player.h)

#pragma once

#include "StDefine.h"

class Player
{
public:
	// プレイヤー
	const constexpr int PLAYER_WID = 32;		// プレイヤー画像の横サイズ
	const constexpr int PLAYER_HIG = 19;		// プレイヤー画像の縦サイズ
	const constexpr int PLAYER_MOVE_SPEED = 6;      // プレイヤーの左右の移動速度
	const constexpr int PLAYER_PLANE_MAX = 3;	// プレイヤーの最大保有機数

	Player(void);
	~Player(void);

	bool SystemInit(void);	//初期化処理(最初の1回のみ実行)
	void GameInit(void);	//ゲーム起動・再開時に必ず呼び出す関数
	void Update(void);		//更新処理
	void Draw(void);		//描画処理
	bool Release(void);		//解放処理(最後の1回のみ実行)

	POSITION GetPos(void) { return pos; }
	bool GetAlive(void) { return aliveFlg; }
	void SetAliveOn(void) { aliveFlg = true; }
	void SetAliveOff(void) { aliveFlg = false; }
	int GetPlayerStock(void) { return playerStock; }
	void playerStockDec(void) { playerStock--; }
	void SetDefaultPos(void);

private:
	int img;		//プレイヤー画像のハンドル番号を格納する変数
	POSITION pos;		//プレイヤーの座標
	bool aliveFlg;		//プレイヤーの存在フラグ(true:生存、false:撃破)
	int playerStock;	//プレイヤーの残機
};

(GameScene.cpp)

/*------------------------------------------------------------
*Player弾と敵との当たり判定
*Input:
*  無し
*Output:
*  true = 命中 / false = はずれ
*/------------------------------------------------------------
bool GameScene::CollisionCheckPlayerBullet(void)
{
	if (pBullet->GetAlive() == true) {
		for (int yy = 0; yy < Enemy::ENEMY_DISP_YNUM; yy++) {
			for (int xx = 0; xx < Enemy::ENEMY_DISP_XNUM; xx++) {
				if (en->GetAlive(xx,yy) == false)continue;
				if (
					(epos.y + Enemy::ENEMY_HIG > pBullet->GetPos().y &&				//判定1:敵の下端のY座標 > 弾の上端のY座標
					(epos.y < pBullet->GetPos().y + Player::PLAYER_BULLET_HIG) &&	//判定2:敵の上端のY座標 < 弾の下端のY座標
					(epos.x < pBullet->GetPos().x + Player::PLAYER_BULLET_WID) &&	//判定3:敵の左端のX座標 < 弾の右端のX座標 
					(epos.x + Enemy::ENEMY_WID > pBullet->GetPos().x)				//判定4: 敵の右端のX座標 > 弾の左端のX座標
					)
				{
					// プレイヤー弾は消滅
					pBullet->SetAliveOff();
					// 敵キャラも消滅
					en->SetAliveOff(xx,yy);
					return true;
				}
			}

		}
	}
	return false;
}


bool GameScene::CollisionCheckEnemyBullet(void)
{
	if (pl->GetAlive == false) return false;
	{
		for (int yy = Enemy::Enemy_DISP_YNUM -1; yy >= 0; yy--) {
			for (int xx = 0; xx < Enemy::ENEMY_DISP_XNUM; xx++) {
				if (eBullet->GetAlive(xx.yy) == true) {
					//敵弾が存在している
					POSITION ebPos = eBullet->GetPos(xx,yy);
					if ((pl->GetPos().y + Player::PLAYER_HIG > ebPos.y)					//プレイヤーの下端>敵弾の上端
						&& (pl->GetPos().y < ebPos.y + EnemyBullete::ENEMY_BULLET_HIG)	//プレイヤーの上端<敵弾の下端
						&& (pl->GetPos().x < ebPos.x + EnemyBullet::ENEMY_BULLET_WID)	//プレイヤーの左端<敵弾の右端
						&& (pl->GetPos.x + Player:: PLAYER_WID > ebPos.x))				//プレイヤーの右端>敵弾の左端
					{
						//プレイヤーに命中
						eBullet->SetAliveOff(xx,yy);
						pl->SetAliveOff();
						return true;
					}
				}
			}

		}
	}
	return false;
}

テスト処理用の変数をクラスに追加。
(GameScene.h)

#pragma once

#include"StDefine.h"

class SceneManager;
class Player;
class PlayerBullet;
class Enemy;
class EnemyBullet;

class GameScene
{
public:
	static constexpr int STAGE_NUM_MAX = 5;	//最大ステージ数

	GameScene(SceneManager* scenem);
	~GameScene(void);

	bool SystemInit(void);		//ゲーム起動時の初期化処理
	void GameInit(void);		//ゲームシーンの初期化処理
	void SceneGameNextStageInit(void);//ステージクリア時の初期化処理
	void Update(void);			//ゲームシーンの更新処理
	void Draw(void);			//ゲームシーンの描画処理
	bool Release(void);			//ゲームシーンの解放処理

	void ExitConditionProc(void);

	eSceneKind getNextSceneID(void) { return nextScene_ID; }

private:
	SceneManager* sceneM;		//SceneManagerClassのインスタンスのポインタ
	Player* pl;					//PlayerClassのインスタンスのポインタ
	PlayerBullet* pBullet;		//PlayerBulletClassのインスタンスのポインタ
	Enemy* en;					//EnemyClassのインスタンスのポインタ
	EnemyBullet* eBullet;		//EnemyBulletのインスタンスのポインタ

	int nowStageNo;				//現在のステージ番号

	eStageExitConditionsKind StageExitConditionsCheck(void);
	
	bool CollisionCheckPlayerBullet(void);//衝突判定
	bool CollisionCheckEnemyBullet(void); //敵弾との衝突判定

	eSceneKind nextScene_ID;	//次に遷移するシーンのID番号

	// テスト用のキーの状態
#ifdef DEBUG

	int nowWKeyPress;	//デバッグ用(W)
	int prevWKeyPress;
	int nowLKeyPress;	//デバッグ用(L)
	int prevLKeyPress;
	int nowOKeyPress;	//デバッグ用(O)
	int prevOKeyPress;
	int nowBKeyPress;	//デバッグ用(B)
	int prevBKeyPress;

#endif // DEBUG

};

Update()を編集。
(GameScene.cpp)

void GameScene::Update(void)
{
	//プレイヤーの移動
	pl->Update();


	// プレイヤー弾の移動処理
	pBullet->UpdateMove();

	// プレイヤー弾の発射処理
	pBullet->UpdateShot();


	//敵の移動処理
	en->UpdateMove();

	//敵弾の移動処理
	eBullet->UpdateMove();

	//敵弾の発射処理
	eBullet->UpdateShot();


	// 当たり判定
	CollisionCheckPlayerBullet();
	CollisionCheckEnemyBullet();

	//--------------------------------------------
	// テスト用処理
	//--------------------------------------------
#ifdef _DEBUG
	prevWKeyPress = nowWKeyPress;
	nowWKeyPress = CheckHitKey(KEY_INPUT_W);
	prevWKeyPress = nowWKeyPress;
	nowLKeyPress = CheckHitKey(KEY_INPUT_L);
	prevLKeyPress = nowLKeyPress;
	nowKeyOPress = CheckHitKey(KEY_INPUT_O);
	prevBKeyPress = nowBKeyPress;
	nowBKeyPress = CheckHitKey(KEY_INPUT_B);
//ここから下は次回以降
	if (nowWKeyPress == 0 && prevWKeyPress == 1) {
		//条件1:プレイヤーが勝った
		//敵キャラを無条件にすべてやられた状態にする
		for (int yy = 0; yy < ENEMY_DISP_YNUM; yy++) {
			for (int xx = 0; xx < ENEMY_DISP_XNUM; xx++) {
				enemyFlgArray[yy][xx] = false;
			}
		}
	}
	else if (nowLKeyPress == 0 && prevLKeyPress == 1) {
		//条件2:敵弾にプレイヤーが撃たれた
		playerFlg = false;
	}
	else if (nowOKeyPress == 0 && prevOKeyPress == 1) {
		//条件3:敵に最下段まで到達された
		//敵キャラをすべてのY座標を最下段に変更
		int chkpos = WINDOW_HIG - ENEMY_MOVE_Y_SPEED; //あと一歩で下端に到達する位置
		for (int yy = ENEMY_DISP_YNUM - 1; yy >= 0; yy--) {
			for (int xx = 0; xx < ENEMY_DISP_XNUM; xx++) {
				if (enemyFlgArray[yy][xx] == true) {
					enemyPosyArray[yy][xx] = chkpos - (ENEMY_MOVE_Y_SPEED * (ENEMY_DISP_YNUM - (yy + 1)));
				}
			}
		}
	}
	else if (nowBKeyPress == 0 && prevBKeyPress == 1) {
		//敵を1段押し戻す
		PlayerBullet::Bomb();
	}
#endif

}

コメント

タイトルとURLをコピーしました