2Dゲーム制作Ⅰ⑯(2025/07/14)

シーン遷移の組み込み

初期化(main.cpp)

//--------------------------
//初期化処理
//--------------------------
    sceneKind = SCENE_KIND_TITLE;

ゲームループ部分にシーン分岐を作成。(main.cpp)
Update()やDraw()はのちに組み込むので、削除。

//-----------------
// ゲームループ
//-----------------
while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) {
    //シーンごとに呼び出す処理を変える
    switch (sceneKind) {
    case SCENE_KIND_TITLE:
        break;
    case SCENE_KIND_GAME:
        break;
    case SCENE_KIND_GAMEOVER:
        break;
    default:
        break;
    }

}

SceneTitle.cppを作成して関数を追加。

#include <DxLib.h>
#include <time.h>
#include"main.h"
#include"SceneTitle.h"
#include"SceneGame.h"
#include"SceneGameOver.h"

// タイトルシーンの初期化処理
bool SceneTitleInit(void)
{
	sceneKind = SCENE_KIND_GAME;
	return true;
}
// タイトルシーンのメイン処理 ※ほかの処理を盛り込んで、こちらを他から呼び出す。
void SceneTitleMainProc(void)
{
	SceneTitleUpdate();
	SceneTitleDraw();
}
// タイトルシーンの更新処理
void SceneTitleUpdate(void)
{
}
// タイトルシーンの描画処理
void SceneTitleDraw(void)
{
}
// タイトルシーンの解放処理
bool SceneTitleRelease(void)
{
	return true;
}

関数を追加:GameScene.cpp

#include <DxLib.h>
#include "main.h"
#include "SceneGame.h"

//ゲームシーンの初期化処理
bool SceneGameInit(void)
{
	return true;
}

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

}

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

}

//ゲームシーンの描画処理
void SceneGameDraw(void)
{

}

//ゲームシーンの解放処理
void SceneGameRelease(void)
{
	return true;
}

プロトタイプ宣言:GameScene.h

#pragma once

//---------------------------------
// 定数定義
//---------------------------------


//---------------------------------
//他のファイルでも参照が必要な変数のextern宣言
//---------------------------------




//-------------------------------------------------
// プロトタイプ宣言
//-------------------------------------------------
bool SceneGameInit(void);//ゲームシーンの初期化処理
void SceneGameMainProc(void);//ゲームシーンのメイン処理
void SceneGameUpdate(void);//ゲームシーンの更新処理
void SceneGameDraw(void);//ゲームシーンの描画処理
void SceneGameRelease(void);//ゲームシーンの解放処理

main.cpp⇒SceneGame.cppに
ゲームシーン関連の初期化処理を移動

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

	return true;
}

SceneGameMainProc()に関数を追加

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

main.cppにincludeするファイルを追加。

//-----------------------------------------------------------------------------
// インベーダーゲーム
// 氏 名:
//-----------------------------------------------------------------------------
#include <DxLib.h>
#include <time.h>
#include"main.h"
#include"Player.h"
#include"PlayerBullet.h"
#include"Enemy.h"
#include"SceneTitle.h"
#include"SceneGame.h"
#include"SeeneGameOver.h"

Main()内に初期化と、各シーンのメイン処理呼び出しを追加。

//-----------------
// WinMain関数
//-----------------
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
	if (Init() == false)return -1;

	SceneTitleInit();
	SceneGameInit();

	//-----------------
	// ゲームループ
	//-----------------
	while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) {
		//シーンごとに呼び出す処理を変える
		switch (sceneKind) {
		case SCENE_KIND_TITLE:
			SceneTitleMainProc();
			break;
		case SCENE_KIND_GAME:
			SceneGameMainProc();
			break;
		case SCENE_KIND_GAMEOVER:
			break;
		default:
			break;
		}

	}

ゲームオーバー処理関数(今の中身は空)を作成:SceneGameOver.cpp

#include <DxLib.h>
#include"main.h"
#include"SceneGameOver.h"

//-----------------
// 変数の宣言
//-----------------

//ゲームオーバーシーンの初期化処理
bool SceneGameOverInit(void)
{
	sceneKind = SCENE_KIND_TITLE;
	return true;
}
//ゲームオーバーシーンのメイン処理
void SceneGameOverMainProc(void)
{
	SceneGameOverUpdate();
	SceneGameOverDraw();
}
//ゲームオーバーシーンの更新処理
void SceneGameOverUpdate(void)
{

}
//ゲームオーバーシーンの描画処理
void SceneGameOverDraw(void) 
{

}
//ゲームオーバーシーンのリリース処理
bool SceneGameOverRelease(void)
{
	return  true;
}

プレイヤー機数を格納する変数を宣言:Player.cpp

int playerOwnPlaneNum;	//プレイヤーの現在の機数

プレイヤーの初期機数を定数化と同時に変数をextern宣言:Player.h

#pragma once

//-----------------
// 定数定義
//-----------------
// プレイヤー
const int PLAYER_WID = 32;				// プレイヤー画像の横サイズ
const int PLAYER_HIG = 19;				// プレイヤー画像の縦サイズ
const int PLAYER_MOVE_SPEED = 6;		// プレイヤーの左右の移動速度
const int PLAYER_PLANE_MAX = 3;			// プレイヤーの最大保有機数
//------------------------------------------
//他のファイルでも参照が必要な変数の extern宣言
//------------------------------------------
extern int playerPosX;		// 自機のX座標
extern int playerPosY;		// 自機のY座標
extern bool playerFlg;		// 自機の表示状態管理用フラグ(true:表示、false:非表示)
extern int playerOwnPlaneNum;	// プレイヤーの現在の機数
//-------------------------------------------
//プロトタイプ宣言
//-------------------------------------------
bool PlayerInit(void);
void PlayerMove(void);
void PlayerDraw(void);

ステージ終了状況のチェックを組み込む:SceneGame.cpp

#include <DxLib.h>
#include "main.h"
#include "SceneGame.h"
#include "Player.h"
#include "PlayerBullet.h"
#include "Enemy.h"

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

	return true;
}

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

	//ステージが終了したか
	eStageexitConditionKind exit = StageExitConditionsCheck();
	if (exit != SCENE_EXIT_NON) {
		sceneKind = SCENE_KIND_GAMEOVER;
	}

}

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

	// プレイヤー弾の発射処理
	PlayerBulletShot();

	// プレイヤー弾の移動処理
	PlayerBulletMove();

	//敵の移動処理
	EnemyMove();


	// 当たり判定

}

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

	// プレイヤーの描画
	PlayerDraw();

	// プレイヤー弾の描画
	PlayerBulletDraw();

	// 敵の描画
	EnemyDraw();

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

//ゲームシーンの解放処理
void SceneGameRelease(void)
{
	return;
}

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

eStageExitConditionsKind StageExitConditionsCheck(void)
{
	eStageExitConditionsKind exitCondition = ESTAGE_EXIT_NON;

	//敵の残機数を取得する
	int enemyNum = 0;
	for (int yy = 0; yy < ENEMY_DISP_YNUM; yy++) {
		for (int xx = 0;xx < ENEMY_DISP_XNUM;xx++) {
			if (enemyFlgArray[yy][xx] == true)enemyNum++;
		}
	}
	if (enemyNum == 0) {
		//敵の残機数が0なので、プレイヤーがステージをクリアした
		exitCondition = ESTAGE_EXIT_CLEAR;
	}
	else if (playerFlg == false) {
		//プレイヤーがやられた
		exitCondition = ESTAGE_EXIT_ENEMY_SHOT;
	}
	else if (CheckHitEdgeProc() == ENEMY_HIT_EDGE_DOWN) {
		//敵が最下段に到達した
		exitCondition = ESTAGE_EXIT_ENEMY_OCCUPATION;
	}
	return exitCondition;
}

衝突判定

当たり判定を作成。今回は矩形:SceneGame.cpp

※弾と敵の矩形同士の当り判定
敵の機体と弾の位置の重なりチェックを行う。
a) 判定パターン1
 敵の機体の下端のY座標 > 弾の上端のY座標
 (enemyPosY+ENEMY_SIZE_HIG > bulletPosY)

b) 判定パターン2
 敵の機体の上端のY座標 < 弾の下端のY座標
 (enemyPosY < bulletPosY+BULLET_SIZE_HIG)

c) 判定パターン3
敵の機体の左端のX座標 < 弾の右端のX座標
(enemyPosX < bulletPosX+BULLET_SIZE_WID)

d) 判定パターン4
敵の機体の右端のX座標 > 弾の左端のX座標
(enemyPosX+ENEMY_SIZE_WID > bulletPosX)

上記の a)~ d) の4つの条件が全て成立した状態ならば、弾が敵に命中したと判断できる。

衝突判定を組み込み:SceneGame.cpp

#include <DxLib.h>
#include "main.h"
#include "SceneGame.h"
#include "Player.h"
#include "PlayerBullet.h"
#include "Enemy.h"

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

	return true;
}

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

	//ステージが終了したか
	eStageExitConditionsKind exit = StageExitConditionsCheck();
	if (exit != ESTAGE_EXIT_NON) {
		sceneKind = SCENE_KIND_GAMEOVER;
	}

}

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

	// プレイヤー弾の発射処理
	PlayerBulletShot();

	// プレイヤー弾の移動処理
	PlayerBulletMove();

	//敵の移動処理
	EnemyMove();


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

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

	// プレイヤーの描画
	PlayerDraw();

	// プレイヤー弾の描画
	PlayerBulletDraw();

	// 敵の描画
	EnemyDraw();

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

//衝突判定
bool CollisionCheckPlayerBullet(void)
{
	if (playerBulletFlg == true) {
		for (int yy = 0; yy < ENEMY_DISP_YNUM; yy++) {
			for (int xx = 0; xx < ENEMY_DISP_XNUM; xx++) {
				if (enemyFlgArray[yy][xx] == false)continue;
				if (
					(enemyPosyArray[yy][xx] + ENEMY_HIG > playerBulletPosY) &&			//判定1:敵の下端のY座標 > 弾の上端のY座標
					(enemyPosyArray[yy][xx] < playerBulletPosY + PLAYER_BULLET_HIG) &&	//判定2:敵の上端のY座標 < 弾の下端のY座標
					(enemyPosxArray[yy][xx] < playerBulletPosX + PLAYER_BULLET_WID) &&	//判定3:敵の左端のX座標 < 弾の右端のX座標 
					(enemyPosxArray[yy][xx] + ENEMY_WID > playerBulletPosX)				//判定4: 敵の右端のX座標 > 弾の左端のX座標
					)
				{
					// プレイヤー弾は消滅
					playerBulletFlg = false;
					// 敵キャラも消滅
					enemyFlgArray[yy][xx] = false;
					return true;
				}
			}
			
		}
	}
	return false;
}

//ゲームシーンの解放処理
void SceneGameRelease(void)
{
	return;
}

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

eStageExitConditionsKind StageExitConditionsCheck(void)
{
	eStageExitConditionsKind exitCondition = ESTAGE_EXIT_NON;

	//敵の残機数を取得する
	int enemyNum = 0;
	for (int yy = 0; yy < ENEMY_DISP_YNUM; yy++) {
		for (int xx = 0;xx < ENEMY_DISP_XNUM;xx++) {
			if (enemyFlgArray[yy][xx] == true)enemyNum++;
		}
	}
	if (enemyNum == 0) {
		//敵の残機数が0なので、プレイヤーがステージをクリアした
		exitCondition = ESTAGE_EXIT_CLEAR;
	}
	else if (playerFlg == false) {
		//プレイヤーがやられた
		exitCondition = ESTAGE_EXIT_ENEMY_SHOT;
	}
	else if (CheckHitEdgeProc() == ENEMY_HIT_EDGE_DOWN) {
		//敵が最下段に到達した
		exitCondition = ESTAGE_EXIT_ENEMY_OCCUPATION;
	}
	return exitCondition;
}

プロトタイプ宣言も追加:GameScene.cpp

#pragma once

//---------------------------------
// 定数定義
//---------------------------------


//---------------------------------
//他のファイルでも参照が必要な変数のextern宣言
//---------------------------------




//-------------------------------------------------
// プロトタイプ宣言
//-------------------------------------------------
bool SceneGameInit(void);//ゲームシーンの初期化処理
void SceneGameMainProc(void);//ゲームシーンのメイン処理
void SceneGameUpdate(void);//ゲームシーンの更新処理
void SceneGameDraw(void);//ゲームシーンの描画処理
void SceneGameRelease(void);//ゲームシーンの解放処理

eStageExitConditionsKind StageExitConditionsCheck(void);

bool CollisionCheckPlayerBullet(void);//衝突判定

上記までの実装で、敵を打ち落とすところまで動作できた。

現時点のソースファイル↓

コメント

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