(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 に渡す
🧠 構造レベルの意味:親子関係の構築
TitleScene
はSceneManager
によって管理される「シーンの一種」です。this
を渡すことで、TitleScene
は「自分を管理している SceneManager にアクセスできる」ようになります。- これは 依存関係の注入(Dependency Injection) の一形態で、構造的には「親を知っている子」を作っているわけです。
🧘♂️ 哲学レベルの意味:自己認識と文脈の継承
TitleScene
に this
を渡すことで、「私は 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:
};
コメント