2Dゲーム制作⑰(2025/07/24)

タイトルシーンの作成

sceneTitle.cppに変数を宣言

int titleImage;		//タイトル画像のハンドル番号
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool SceneTitleInit(void)
{
	titleImage = LoadGraph("image/title.png");
	if (titleImage == -1)return false;
	
	return true;
}

ゲームシーンへの遷移

スペースキーが押されたらゲームシーンへ遷移するように組んでいく。
ただし、CheckHitKey(KEY_INPUT_SPACE == 1)を条件として使うと、ゲーム開始時に弾が発射されてしまうようになる。CheckHitKeyはダウントリガーの為。
 「ダウントリガー」:押した瞬間に反応する。
 「アップトリガー」:キーを離した瞬間に反応する。

この場合、「アップトリガー」を使うと問題が解決できる。

スペースキーの入力状態を格納する変数を宣言(main.cpp)

//変数宣言
eSceneKind sceneKind;	//現在のシーンを格納する変数
eStageExitConditionsKind StageExitConditionsKind; //ゲームの進行状況を格納する変数
int nowSpaceKey;		//スペースキーの現在のフレームでの状態を格納
int prevSpaceKey;		//スペースキーの直前のフレームでの状態を格納

変数を初期化(main.cpp)

	//--------------------------
	//初期化処理
	//--------------------------
		sceneKind = SCENE_KIND_TITLE;
		nowSpaceKey = prevSpaceKey = 0;

extern宣言もしておく(main.h)

//-----------------------------------------------
//他のファイルでも参照が必要なもののextern宣言
//-----------------------------------------------
extern eSceneKind sceneKind;
extern int nowSpaceKey;
extern int prevSpaceKey;

ゲームループ内にスペースキーの状態更新を組み込む(main.cpp)

	//-----------------
	// ゲームループ
	//-----------------
	while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) {
		//スペースキーの状態を更新
		prevSpaceKey = nowSpaceKey;//現在のスペースキーの状態を前のキー状態にコピー
		nowSpaceKey = CheckHitKey(KEY_INPUT_SPACE);//現在のスペースキーの状態を更新

		//シーンごとに呼び出す処理を変える
		switch (sceneKind) {
		case SCENE_KIND_TITLE:
			SceneTitleMainProc();
			break;
		case SCENE_KIND_GAME:
			SceneGameMainProc();
			break;
		case SCENE_KIND_GAMEOVER:
			break;
		default:
			break;
		}

画面遷移と更新を組み込む(sceneTitle.ccp)
タイトルからのシーン遷移は「アップトリガー」で判定。

//-------------------------
// 変数の宣言
//--------------------------
int titleImage;		//タイトル画像のハンドル番号

// タイトルシーンの初期化処理
bool SceneTitleInit(void)
{
	titleImage = LoadGraph("image/title.png");
	if (titleImage == -1)return false;
	
	return true;
}
// タイトルシーンのメイン処理 ※ほかの処理を盛り込んで、こちらを他から呼び出す。
void SceneTitleMainProc(void)
{
	SceneTitleUpdate();
	SceneTitleDraw();
}
// タイトルシーンの更新処理
void SceneTitleUpdate(void)
{
	if (nowSpaceKey == 0 && prevSpaceKey ==1) {
		sceneKind = SCENE_KIND_GAME;
	}
}
// タイトルシーンの描画処理
void SceneTitleDraw(void)
{
	SetDrawScreen(DX_SCREEN_BACK);		//描画する画面を裏の画面に設定する
	ClearDrawScreen();			//描画する画面の内容を消去する

	DrawGraph(0, 0, titleImage, true);

	ScreenFlip();				//裏の画面を表の画面に切り替え
}

プレイヤーの弾発射をダウントリガーに変更
(ゲームの仕様によるが、今回はダウントリガーを試してみる為)

void PlayerBulletShot(void) {
	if (playerBulletFlg == false) {
		//弾が未発射状態なので射撃可能
		if (nowSpaceKey == 1 && prevSpaceKey == 0) {
			playerBulletPosX = (playerPosX + PLAYER_WID / 2) - (PLAYER_BULLET_WID / 2);
			playerBulletPosY = playerPosY - PLAYER_BULLET_HIG;
			playerBulletFlg = true;
		}
	}

}

タイトル画像が画面サイズと合っていないので、センタリングする(SceneTitle.h)

const int TITLE_WID = 800;//タイトル画像の幅
const int TITLE_HIG = 475;//タイトル画像の高さ

表示位置をセンタリングする

// タイトルシーンの描画処理
void SceneTitleDraw(void)
{
	SetDrawScreen(DX_SCREEN_BACK);		//描画する画面を裏の画面に設定する
	ClearDrawScreen();			//描画する画面の内容を消去する

	int xx = (WINDOW_WID - TITLE_WID) / 2;
	int yy = (WINDOW_HIG - TITLE_HIG) / 2;
	DrawGraph(xx, yy, titleImage, true);

	ScreenFlip();				//裏の画面を表の画面に切り替え
}

※今回は定数で指定しているが、画像サイズや画面サイズを取得する関数もある。こういったものをUpdate内で呼ぶと毎回アクセスが発生して処理がかさむので、Init等で一度だけ読み込んで、値を保持しておくこと。

さらに、”HIT SPACE KEY!”も表示するためにDrawStringを追加する(SceneTitle.cpp)

// タイトルシーンの描画処理
void SceneTitleDraw(void)
{
	SetDrawScreen(DX_SCREEN_BACK);		//描画する画面を裏の画面に設定する
	ClearDrawScreen();				//描画する画面の内容を消去する

	//タイトル画像表示
	int xx = (WINDOW_WID - TITLE_WID) / 2;
	int yy = (WINDOW_HIG - TITLE_HIG) / 2;
	DrawGraph(xx, yy, titleImage, true);

	//文字列表示
	xx = (WINDOW_WID - 100) / 2;
	yy = (WINDOW_HIG - 200);
	DrawString(xx,yy,"HIT SPACE KEY!", 0xffffff);

	ScreenFlip();					//裏の画面を表の画面に切り替え
}

プレイヤーの保有機数の実装

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

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

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

	// 敵の描画
	EnemyDraw();

	//文字列表示
	DrawFormatString(10, 10, 0xffffff, "PlayerStock:%d", playerStock);

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

ステージ終了時の処理作成(デバッグ用)

テスト用のキー入力状態格納のための変数を宣言(SceneGame.cpp)

// 変数宣言
// テスト用のキーの状態
int nowWKeyPress;
int prevWKeyPress;
int nowLKeyPress;
int prevLKeyPress;
int nowOKeyPress;
int prevOKeyPress;
//---------------------------------
//他のファイルでも参照が必要な変数のextern宣言
//---------------------------------
// テスト用のキーの状態
extern int nowWKeyPress;
extern int prevWKeyPress;
extern int nowLKeyPress;
extern int prevLKeyPress;
extern int nowOKeyPress;
extern int prevOKeyPress;

ゲームループ内に組み込み(main.cpp)

	//-----------------
	// ゲームループ
	//-----------------
	while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) {
		//スペースキーの状態を更新
		prevSpaceKey = nowSpaceKey;
                //現在のスペースキーの状態を前のキー状態にコピー
		nowSpaceKey = CheckHitKey(KEY_INPUT_SPACE);	//現在のスペースキーの状態を更新
		//テスト用処理
		prevWKeyPress = nowWKeyPress;
		nowWKeyPress = CheckHitKey(KEY_INPUT_W);
		prevLKeyPress = nowLKeyPress;
		nowLKeyPress = CheckHitKey(KEY_INPUT_L);
		prevOKeyPress = nowOKeyPress;
		nowOKeyPress = CheckHitKey(KEY_INPUT_O);


		//シーンごとに呼び出す処理を変える
		switch (sceneKind) {
		case SCENE_KIND_TITLE:
			SceneTitleMainProc();
			break;
		case SCENE_KIND_GAME:
			SceneGameMainProc();
			break;
		case SCENE_KIND_GAMEOVER:
			break;
		default:
			break;
		}

	}

初期化も組み込み。(main.cpp)

bool Init(void)
{
	//-----------------
	// システム設定
	//-----------------
	SetWindowText("****** ******");	  // ウィンドウのタイトルの設定
	SetGraphMode(WINDOW_WID, WINDOW_HIG, 32);// ウィンドウのサイズと色モードの設定
	ChangeWindowMode(true);	// ウィンドウの表示モード(true=ウィンドウモード/false=フルスクリーン)

	int err = DxLib_Init();					// DXライブラリの初期化
	if (err == -1)return false;

	SRand((unsigned int)time(NULL));

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

		nowSpaceKey = prevSpaceKey = 0;

	// ------------------------------------------------------------------
	// テスト用処理
	//------------------------------------------------------------------
		prevWKeyPress = nowWKeyPress = 0;
		prevLKeyPress = nowLKeyPress = 0;
		prevOKeyPress = nowOKeyPress = 0;

	return true;
}

次回は入力に応じた処理を組み込んでいくところから。

コメント

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