2Dゲーム制作㉒(2025/09/04)

(TitleScene.cpp)

//初期化処理(最初の一回のみ実行)
bool TitleScene::SystemInit(void)
{
	titleImage = LoadGraph("image/title.png");
	if (titleImage == -1)return false;

	nextScene_ID = SCENE_KIND_TITLE; //(ここに置く意味は録画00:10くらいを確認

	return true;

}

更新処理にシーン遷移を組み込み。
(TitleScene.cpp)

//更新処理
void TitleScene::Update(void)
{
	int nowKey = sceneM->GetNowSpaceKey();
	int prevKey = sceneM->GetPrevSpaceKey();

	if (nowKey == 0 && prevKey == 1) {
		//アップトリガーでスペースキーの押下を判定
		//SceneGameSysInit();
		//SceneGameInit();
		nowStageNum = 1;
		sceneKind = SCENE_KIND_GAME;
		nextScene_ID = SCENE_KIND_GAME;
	}

}

描画処理を古い関数から移植。Applicationクラス内の定義を参照するため、定数にApplication::をつける。クラスの定義元であるApplication.hのインクルードも忘れないように。
(SceneTitle.cpp)

#include "Application.h"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//描画処理
void TitleScene::Draw(void)
{
	//タイトル画像表示
	int xx = (Application::WINDOW_WID - TITLE_WID) / 2;
	int yy = (Application::WINDOW_HIG - TITLE_HIG) / 2;
	DrawGraph(xx, yy, titleImage, true);

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

}

メンバ関数についてはアロー演算子(->)で参照。
定数に関してはスコープ演算子(::)で参照する。

古いコードの残骸を削除。
(TitleScene.cpp)

// タイトルシーンの初期化処理
bool SceneTitleInit(void)
{
	
	return true;
}
// タイトルシーンのメイン処理 ※ほかの処理を盛り込んで、こちらを他から呼び出す。
void SceneTitleMainProc(void)
{
	SceneTitleUpdate();
	SceneTitleDraw();
}
// タイトルシーンの更新処理
void SceneTitleUpdate(void)
{
}
// タイトルシーンの描画処理
void SceneTitleDraw(void)
{
	SetDrawScreen(DX_SCREEN_BACK);		//描画する画面を裏の画面に設定する
	ClearDrawScreen();					//描画する画面の内容を消去する


	ScreenFlip();						//裏の画面を表の画面に切り替え
}
// タイトルシーンの解放処理
bool SceneTitleRelease(void)
{
	if (DeleteGraph(titleImage) == -1)return false;
	return true;
}

SceneTitleReleaseからDeleteGraphを移動するのを忘れていたので移動。
(TitleScene.cpp)

//解放処理(最後の一回のみ実行)
bool TitleScene:: Release(void)
{
	if (DeleteGraph(titleImage) == -1)return false;
	return true;
}

eSceneKind型を参照するためインクルードを追加。
(TitleScene.h)

#include"StDefine.h"

ここまででSceneTitleクラスは完成。SceneManagerクラスから呼び出してタイトル画面が表示できるようにしていく。
(SceneManager.h)

#pragma once

#include "StDefine.h"

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

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;	//タイトルシーンのインスタンスのポインタ

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

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

コンストラクタにインスタンスのポインタ初期化を追加。同時にTitleScene.hもインクルードする
(SceneManager.cpp)

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

//コンストラクタ
SceneManager::SceneManager(void)
{
	scene_ID = SCENE_KIND_NON;//
	title = nullptr;
}

SystemInit()内でTitleSceneクラスのオブジェクトを生成する。(new)
生成が失敗した場合の判定も記述して、失敗していなければSystemInit()を呼び出す。

(SceneManager.cpp)

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

	scene_ID = SCENE_KIND_TITLE;

	prevSpaceKey = nowSpaceKey = 0;
	return true;
}

title = new TitleScene(this);
この意味は、「TitleScene のインスタンスを作成し、SceneManager のインスタンス(自身)のポインタを渡して格納」ということ。

~thisについて~
this はC++の中でも、構造的な意味を深く考えるうえで非常に面白いキーワードです。
このコードにおける this の意味を、構造・哲学・実装の3層で分解してみましょう。

🧱 実装レベルの意味:this は「自分自身のポインタ」

  • SceneManager::SystemInit()SceneManager クラスのメンバ関数です。
  • その中で new TitleScene(this); と書かれているので、this現在の SceneManager インスタンスのポインタ を意味します。
  • つまり、TitleScene のコンストラクタに「この SceneManager を指すポインタ」を渡しているわけです。
title = new TitleScene(this); // ← SceneManager のポインタを TitleScene に渡す

🧠 構造レベルの意味:親子関係の構築

  • TitleSceneSceneManager によって管理される「シーンの一種」です。
  • this を渡すことで、TitleScene は「自分を管理している SceneManager にアクセスできる」ようになります。
  • これは 依存関係の注入(Dependency Injection) の一形態で、構造的には「親を知っている子」を作っているわけです。

🧘‍♂️ 哲学レベルの意味:自己認識と文脈の継承

TitleScenethis を渡すことで、「私は SceneManager という文脈の中で存在している」という情報を継承させている。
this は「自分自身を指す」という意味で、オブジェクト指向における 自己認識の象徴 です。

🧘‍♂️ たとえるなら…

SceneManager は「家主」で、TitleScene は「別の場所に住んでいる住人」。
家主は住人の住所(ポインタ)を知っていて、連絡を取れるけれど、住人は家主の家の中に住んでいるわけではない。

そして this を渡すことで、住人(TitleScene)は「家主の連絡先」を知っている。
この関係性が、双方向の依存関係を可能にしているわけです。

✅ まとめ

要素実体の場所アドレス含まれているか
SceneManager


(byCopilot)


switchでシーン切り替えを実装。titleインスタンスからDraw()を呼び出す。
(SceneManager.cpp)

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

	switch (scene_ID) {
		case SCENE_KIND_TITLE:
                        title->Update();
			break;
		case SCENE_KIND_GAME;
			break;
		case SCENE_KIND_GAMEOVER;
			break;

	}
}

描画処理にも同様にswitchでDraw()を呼び出す。
(SceneManager.cpp)

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

Release()内でオブジェクトの破棄を書いていく。

//解放処理(最初の一回のみ実行)
bool SceneManager::Release(void)
{
	//タイトルシーンクラスのオブジェクトの破棄
	title->Release(); //titleオブジェクトのRelease()を呼び出し(画像の破棄)
	delete title;   //titleオブジェクトの破棄
	title = nullptr;  //titleにnullポインタを設定

	return true;
}

とりあえずここまででタイトル画面表示はOK。


プロジェクトに、SceneGame.cpp、SceneGame.hを追加。
それぞれGameScene.cpp、GameScene.hにリネーム。

GameSceneClassを作成してゆく。
定数定義をpublic:に転記するところまで。
(GameScene.h)

#pragma once

#include"StDefine.h"

class SceneManager;

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


private:


};

コメント

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