2Dゲーム制作㉗(2025/10/15)

(GameScene.cpp)

#include <DxLib.h>
#include "GameScene.h"
#include "Player.h"
#include "PlayerBullet.h"
#include "Enemy.h"
#include "EnemyBullet.h"
#include "Application.h"
using namespace GameScene;

//コンストラクタ
GameScene::GameScene(SceneManager* scenem)
{
	sceneM = scenem;
	pl = nullptr;
	pBullet = nullptr;
	en = nullptr;
	eBullet = nullptr;
}

//デストラクタ
GameScene::~GameScene(void)
{

}

bool GameScene::SystemInit(void)
{
	pl = new Player();
	if (pl == nullptr)return false;

	pBullet = new PlayerBullet(sceneM,pl);
	if (pBullet == nullptr)return false;

	en = new Enemy();
	if (en == nullptr)return false;

	eBullet = new EnemyBullet(en);
	if (eBullet == nullptr)return false;

	if (pl->SystemInit() == false)return false;
	if (pBullet->SystemInit() == false)return false;
	if (en->SystemInit() == false)return false;
	if (eBullet->SystemInit() == false)return false;

	return true;
}

void GameScene::GameInit(void)
{
	pl->GameInit();
	pBullet->GameInit();
	en->GameInit();
	eBullet->GameInit();

	nowStageNo = 0;
	nextStage_ID = SCENE_KIND_GAME;

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

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

#endif // DEBUG

}

//プレイヤーが勝利した時の再初期化処理
void GameScene::SceneGameNextStageInit(void)
{
	//敵キャラ関連の初期化
	en->GameInit();
	//プレイヤー関連の初期化
	//プレイヤーY座標は常に最下段なので再設定は不要
	//プレイヤー勝利時に呼ばれるので存在フラグの再設定は不要
	pl->SetDefaulotPos();
}

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


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

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


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

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

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


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

	prevBKeyPress = nowBKeyPress;
	nowBKeyPress = CheckHitKey(KEY_INPUT_B);

	if (nowBKeyPress == 0 && prevBKeyPress == 1) {
		//敵を1段押し戻す
		PlayerBullet::Bomb();
	}
	//--------------------------------------------
	// テスト用処理
	//--------------------------------------------
#ifdef _DEBUG
	prevWKeyPress = nowWKeyPress;
	nowWKeyPress = CheckHitKey(KEY_INPUT_W);
	prevWKeyPress = nowWKeyPress;
	nowLKeyPress = CheckHitKey(KEY_INPUT_L);
	prevLKeyPress = nowLKeyPress;
	nowKeyOPress = CheckHitKey(KEY_INPUT_O);
	
	if (nowWKeyPress == 0 && prevWKeyPress == 1) {
		//条件1:プレイヤーが勝った
		//敵キャラを無条件にすべてやられた状態にする
		for (int yy = 0; yy < Enemy::ENEMY_DISP_YNUM; yy++) {
			for (int xx = 0; xx < Enemy:: ENEMY_DISP_XNUM; xx++) {
				en->SetAliveOff(xx,yy);
			}
		}
	}
	else if (nowLKeyPress == 0 && prevLKeyPress == 1) {
		//条件2:敵弾にプレイヤーが撃たれた
		pl->SetAliveOff();
	}
	else if (nowOKeyPress == 0 && prevOKeyPress == 1) {
		//条件3:敵に最下段まで到達された
		//敵キャラをすべてのY座標を最下段に変更
		int chkpos = Application::WINDOW_HIG - Enemy::ENEMY_MOVE_Y_SPEED; //あと一歩で下端に到達する位置
		for (int yy = Enemy::ENEMY_DISP_YNUM - 1; yy >= 0; yy--) {
			for (int xx = 0; xx < Enemy::ENEMY_DISP_XNUM; xx++) {
				if (en->GetAlive(xx,yy) == true) {
					POSITION enPos = en->GetPos(xx.yy);
					enPos.y = chkpos - (Enemy::ENEMY_MOVE_Y_SPEED * (Enemy::ENEMY_DISP_YNUM - (yy + 1)));
				}
			}
		}
	}

	}
#endif

}

void GameScene::Draw(void)
{

	// プレイヤーの描画
	pl->Draw();

	// プレイヤー弾の描画
	pBullet->Draw();

	// 敵の描画
	en->Draw();

	// 敵弾の描画
	eBullet->Draw();

	//文字列表示
	DrawFormatString(10, 10, 0xffffff, "PlayerStock:%d", pl->GetPlayerStock());
	DrawFormatString(10, 28, 0xffffff, "BombStock:%d", pBullet->GetBombStock);
	DrawFormatString(10, 46, 0xffffff, "NowStage:%d", nowStageNum);

	ScreenFlip();							// 裏の画面を表の画面に瞬間コピー

}

bool GameScene::Release(void)
{
	pl->Release();
	delete pl;
	pl = nullptr;

	pBullet->Release();
	delete pBullet;
	pBullet = nullptr;

	en->Release();
	delete en;
	en = nullptr;

	eBullet->Release();
	delete eBullet;
	eBullet = nullptr;

	retrurn true;
}
//ステージ終了処理
void GameScene::ExitConditionProc(void)
{
	//ステージが終了したか
	eStageExitConditionsKind exit = StageExitConditionsCheck();
	if (exit != ESTAGE_EXIT_NON) {
		switch (exit) {
		case ESTAGE_EXIT_CLEAR:
			//条件1:プレイヤー勝利
			//ステージ番号を1加算
			nowStageNo++;
			//ステージ番号が最大ステージ数を超えたらゲーム終了
			if (nowStageNo > STAGE_NUM_MAX)
			{
				nextScene_ID = SCENE_KIND_GAMEOVER;
			}
			else {
				//次のステージに進む際に敵の位置やフラグを再初期化
				SceneGameNextStageInit();
			}
			break;

		case ESTAGE_EXIT_ENEMY_SHOT:
			//条件2:プレイヤーが敵弾にやられた
			pl->playerStockDec();
			if (pl->GetPlayerStock < 0) {
				//保有機数がなくなったらゲームオーバー
				nextScene_ID = SCENE_KIND_GAMEOVER;
			}
			else {
				//保有機数が残っていた場合に続行
				//プレイヤーのみ初期化
				pl->SetDefaultPos();
				pl->SetAliveOn();
			}

			break;
		case ESTAGE_EXIT_ENEMY_OCCUPATION:
			//条件3:敵が最下部に到達したらゲームオーバー
			SceneGameStageInit();//配置初期化
			sceneKind = SCENE_KIND_GAMEOVER;
			break;

		}
	}


}

//状況を検知して返す
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;
}

/*------------------------------------------------------------
*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;


}


//ゲームシーンの初期化処理
bool SceneGameSysInit(void)
{
	if (PlayerSysInit() == false)return false;			//画像の読み込みを行っている為、エラー(falseが返されたとき)に処理を終了させる
	if (PlayerBulletSysInit() == false)return false;	//画像の読み込みを行っている為、エラー(falseが返されたとき)に処理を終了させる
	if (EnemySysInit() == false)return false;			//画像の読み込みを行っている為、エラー(falseが返されたとき)に処理を終了させる
	if (EnemyBulletSysInit() == false)return false;		//画像の読み込みを行っている為、エラー(falseが返されたとき)に処理を終了させる
	return true;
}

void SceneGameInit(void)
{
	PlayerInit();
	PlayerBulletInit();
	EnemyInit();
	EnemyBulletInit();

}

//プレイヤー勝利時の再初期化処理
void SceneGameNextStageInit(void) {
	//敵キャラ関連の初期化
	EnemyInit();
	//プレイヤー関連の初期化
	//プレイヤーのY座標は常に最下段なので初期化不要
	//プレイヤー勝利時の呼び出しになるためPlayerFlagの更新も不要
	playerPosX = (WINDOW_WID - PLAYER_WID) / 2;	//横方向の画面中央に位置を設定
}


//ゲームシーンのメイン処理
void SceneGameMainProc(void)
{
	SceneGameUpdate();
	SceneGameDraw();

}

//ゲームシーンの更新処理
void SceneGameUpdate(void)
{
}

#if0
//ゲームシーンの描画処理
void SceneGameDraw(void)
{
	SetDrawScreen(DX_SCREEN_BACK);			// 描画する画面を裏の画面に設定する
	ClearDrawScreen();						// 描画する画面の内容を消去する

}

//衝突判定
bool CollisionCheckPlayerBullet(void)
{
}

//衝突判定
bool CollisionCheckEnemyBullet(void)
{
}


//ゲームシーンの解放処理
bool SceneGameRelease(void)
{
	if (PlayerRelease() == -1)return false;
	if (PlayerBulletRelease() == -1)return false;
	if (EnemyRelease() == -1)return false;
	if (EnemyBulletRelease() == -1)return false;
	return true;
}

/**
* -----------------------------------------------------
* ステージ終了状況のチェック
* 引数:なし
* 戻り値:
*  ESTAGE_EXIT_NON				--->まだ戦闘中
*  ESTAGE_EXIT_CLEAR			--->条件1:プレイヤーが勝った
*  ESTAGE_EXIT_ENEMY_SHOT		--->条件2:敵弾にプレイヤーが撃たれた
*  ESTAGE_EXIT_ENEMY_OCCUPATION--->条件3:敵に最下段まで到達された
* -----------------------------------------------------
**/

eStageExitConditionsKind StageExitConditionsCheck(void)
{

}
#endif

(SceneManager.h)

#pragma once

#include "StDefine.h"

class TitleScene;	//SceneManagerクラス内でTitleSceneクラスを使う為の宣言
class GameScene;	//SceneManagerクラス内でGameSceneクラスを使うための宣言

class SceneManager
{
public:
	SceneManager(void);		//コンストラクタ
	~SceneManager(void);	//デストラクタ

	bool SystemInit(void);	//初期化処理(最初の一回のみ実行)
	void Update(void);		//更新処理
	void Draw(void);		//描画処理
	bool Release(void);		//解放処理(最後の一回のみ実行)

	int GetNowSpaceKey(void) { return prevSpaceKey; }
	int GetPrevSpaceKey(void) { return prevSpaceKey; }

private:
	TitleScene* title;		//タイトルシーンClassのインスタンスのポインタ
	GameScene* game;		//ゲームシーンClassのインスタンスのポインタ

	eSceneKind scene_ID;	//現在のシーンID番号
	eSceneKind nextStageID;	//次のシーンID番号

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

	int nowSpaceKey;		//スペースキーの現在のフレームでの状態を格納
	int prevSpaceKey;		//スペースキーの直前のフレームでの状態を格納
};

(SceneManager.cpp)

#include<DxLib.h>
#include"SceneManager.h"
#include"TitleScene.h"
#include"GameScene.h"

//コンストラクタ
SceneManager::SceneManager(void)
{
	scene_ID = SCENE_KIND_NON;	//オブジェクト生成時のみに行われるため、数値の初期化は別関数で行う
	title = nullptr;
	game = nullptr;

}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool SceneManager::SystemInit(void)
{
	//オブジェクトの作成
	title = new TitleScene(this);		//titleオブジェクトを作成してSceneManagerインスタンスのポインタを格納
	if (title == nullptr)return false;

	game = new GameScene(this);			//gameオブジェクトを作成してSceneManagerインスタンスのポインタを格納
	if (game == nullptr)return false;

	if(title->SystemInit()==false)return false;
	if(game->SystemInit()==false)return false;

	scene_ID = nextSceneID = SCENE_KIND_TITLE;

	prevSpaceKey = nowSpaceKey = 0;

	return true;
}

(TitleScene.h)

#pragma once

#include"StDefine.h"

class SceneManager;

class TitleScene {

public:
	static constexpr int TITLE_WID = 800;	//タイトル画像の幅
	static constexpr int TITLE_HIG = 475;	//タイトル画像の高さ

	TitleScene(SceneManager* scenem);	//コンストラクタ
	~TitleScene(void);	//デストラクタ

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

	eSceneKind GetNextSceneID(return nextScene_ID;);


private:
	int titleImage;		//タイトル画像のハンドル番号

	SceneManager* sceneM;	//シーンマネージャークラスのインスタンスのポインタ
	eSceneKind nextScene_ID;//次に遷移するシーンのID番号
};

(SceneManager.cpp)

#include<DxLib.h>
#include"SceneManager.h"
#include"TitleScene.h"
#include"GameScene.h"

//コンストラクタ
SceneManager::SceneManager(void)
{
	scene_ID = SCENE_KIND_NON;	//オブジェクト生成時のみに行われるため、数値の初期化は別関数で行う
	title = nullptr;
	game = nullptr;

}

//デストラクタ
SceneManager::~SceneManager(void)
{

}

bool SceneManager::SystemInit(void)
{
	//オブジェクトの作成
	title = new TitleScene(this);		//titleオブジェクトを作成してSceneManagerインスタンスのポインタを格納
	if (title == nullptr)return false;

	game = new GameScene(this);			//gameオブジェクトを作成してSceneManagerインスタンスのポインタを格納
	if (game == nullptr)return false;

	if(title->SystemInit()==false)return false;
	if(game->SystemInit()==false)return false;

	scene_ID = nextSceneID = SCENE_KIND_TITLE;

	prevSpaceKey = nowSpaceKey = 0;

	return true;
}

//更新処理
void SceneManager::Update(void)
{
	//スペースキーの状態を更新
	prevSpaceKey = nowSpaceKey;					//現在のキー状態を直前の状態として保存
	nowSpaceKey = CheckHitKey(KEY_INPUT_SPACE);	//現在のキー状態を更新

	eSceneKind nextSID = scene_ID;//現在のscene_IDを代入(初期化)

	switch (scene_ID) {
		case SCENE_KIND_TITLE:
			title->Update();
			nextSID = title->GetNextSceneID();
			break;
		case SCENE_KIND_GAME:
			game->Update();
			game->ExitConditionProc();
			break;
		case SCENE_KIND_GAMEOVER:
			break;

	}

	if (scene_ID != nextSID) {
		scene_ID = nextSID;
		switch (scene_ID) {
			case SCENE_KIND_TITLE
				title->GameInit();
				break;
			case SCENE_KIND_GAME
				game->GameInit();
				break;
			case SCENE_KIND_GAME_OVER
				break;
		}
	}
}

//描画処理
void SceneManager::Draw(void)
{
	switch (scene_ID) {
	case SCENE_KIND_TITLE:
		title->Draw();
		break;
     	case SCENE_KIND_GAME:
                game->Draw();
		break;
	case SCENE_KIND_GAMEOVER:
		break;
	}
}

//解放処理(最初の一回のみ実行)
bool SceneManager::Release(void)
{
	//タイトルシーンクラスのオブジェクトの破棄
	title->Release();
	delete title;
	title = nullptr;

	game->Release();
	delete game;
	game = nullptr;

	return true;
}

SceneGameOver.cpp、SceneGameOver.hをインポートして
GameOverScene.cpp、GameOverScene.hにリネーム

(GameOverScene.h)

#pragma once

#include"StDefine.h"

class SceneManager;

class GameSceneOver
{
	static constexpr int GAME_OVER_GRAPH_WID = 800;	//ゲームオーバー画像の幅
	static constexpr int GAME_OVER_GRAPH_HID = 500;	//ゲームオーバー画像の高さ

public:
	GameOverScene(SceneManager* scenem);
	~GameOverScene(void);

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

	eSceneKind GetNextSceneID{return nextScene_ID;}

private:
	SceneManager* sceneM;		//SceneManagerClassのInstance

	int img;			//ゲームオーバー画像のハンドル番号
	eSceneKind nextScene_ID;	//次に遷移するシーンのID番号
};

(GameOverScene.cpp)

#include <DxLib.h>
#include"GameOverScene.h"
#include"SceneManager.h"
#include"Application.h"

GameOverScene::GameOverScene(SceneManager* scenem)
{
	SceneM = nullptr;
	img = -1;
	
}

GameOverScene::~GameOverScene(void)
{

}

bool GameOverScene::SystemInit(void)
{
	img = LoadGraph("image/gameOver.png");
	if (img == -1)return false;				//画像読み込みに失敗したら終了

	return true;
}

bool GameOverScene::GameInit(void)
{
	nextSceneID = SCENE_KIND_GAMEOVER;
}

void GameOverScene::Update(void)
{
	int prevKey = sceneM->GetPrevSpaceKey();
	int nowKey = sceneM->GetNowSpaceKey();
	if (nowKey == 0 && prevKey == 1) {
		nextSceneID = SCENE_KIND_TITLE;
	}

}

void GameOverScene::Draw(void)
{
	SetDrawScreen(DX_SCREEN_BACK);	//描画する画面を裏画面に設定
	ClearDrawScreen();				//描画する画面の内容を消去

	int xx = (Application::WINDOW_WID - GameSceneOver::GAME_OVER_GRAPH_WID) / 2;
	int yy = (Application::WINDOW_HIG - GameSceneOver:: GAME_OVER_GRAPH_HID) / 2;
	DrawGraph(xx, yy, img, true);

	xx = Application::WINDOW_WID / 2 - 40;
	yy = (Application::WINDOW_HIG - 40);
	//文字列表示
	DrawString(xx, yy, "Hit Space Key!!!", 0xffffff);

}

bool GameOverScene::Release(void)
{
	if (DeleteGraph(img) == -1)return false;
	return  true;

}

現状エラーがたくさん出てるので修正していく。

コメント

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