その中で、シーンの切り換えの実装にてこずっているため質問させていただきます。
OSはWindows、エディタはVisual Studio 2022を使用しています。
ライブラリは先ほども書いた通り、DXライブラリを使用しています。
C言語については学校の講義で基本的な部分については学んでいます。
どれぐらい理解しているかの指標となるかは分かりませんが、構造体やポインタ渡しについては
理解しているつもりです。
一方で、C++については使用するのは今回が初めてで、クラスについて理解はできていません。
また、ゲーム製作の経験はUnityで簡単なアクションゲームを作った程度です。
以下に示すようなMainファイルとSceneManagerファイル、Titleファイル、SelectSceneファイルを作成し、
MainファイルからSceneManagerファイルのScene_Manage関数を呼び出し、
Scene_Manage関数からさらにTitleファイルやSelectSceneファイルの関数を呼び出すことで
ゲームのシーンの切り換えを行おうとしています。
※以下では今回の質問に関係のない処理について省いて書いています。
/* === Main.cpp === */
#include "DxLib.h"
#include "SceneManager.h"
#include "Title.h"
int Game_Init(void); // 諸々の初期化を行う関数
void Game_End(void); // 諸々の終了処理を行う関数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
SetOutApplicationLogValidFlag(false); // Log.txtの出力の拒否
ChangeWindowMode(true); // ウィンドウモードに設定
SetGraphMode(GameWindowWidth, GameWindowHeight,GameColor); // 解像度の設定
SetWindowSize(GameWindowWidth, GameWindowHeight); // ウィンドウサイズの設定
SetMainWindowText(GameTitle); // ウィンドウのタイトル
SetBackgroundColor(0, 0, 0); // ウィンドウの背景色
SetWaitVSyncFlag(true); // 垂直同期の設定
SetAlwaysRunFlag(true); // 非アクティブでもゲーム実行
/* +++ ゲームの初期化 +++ */
if (Game_Init() == -1) // 初期化に失敗したなら
{
return -1; // ソフトを終了する
}
SetDrawScreen(DX_SCREEN_BACK); // 裏画面に描画(ダブルバッファリング)
/* +++ ゲームループ(無限ループ) +++ */
while (true)
{
/* +++ メッセージを処理し続ける(マウスやキーの入力を受け付け続ける) +++ */
if (ProcessMessage() != 0) // エラー発生やウィンドウが閉じられた
{
break; // ループの終了(ゲームの終了)
}
/* +++ 画面を書き換える(画面を消去する) +++ */
if (ClearDrawScreen() != 0) // エラー発生
{
break; // ループの終了(ゲームの終了)
}
/* +++ キー入力の取得 +++ */
if (Key_class.Key_Check() != 0)
{
break;
}
/* +++ ゲームの動作 +++ */
{
/* +++ SceneManageファイルのScene_Manage関数を実行 +++ */
if (Scene_class.Scene_Manage() == -1)
{
break;
}
}
/* +++ 裏画面を表画面に描画 +++ */
if (ScreenFlip() != 0) // エラー発生
{
break; // ループの終了(ゲームの終了)
}
/* +++ Enterキーを押したらゲームループ終了 +++ */
if (Key_class.key[KEY_INPUT_RETURN] == 1)
{
break;
}
}
Game_End(); // ゲームの終了
return 0; // ソフト終了
}
/* +++ ゲームの初期化処理(ここに諸々の初期化処理を集める) +++ */
int Game_Init(void)
{
/* --- Dxライブラリ初期化処理 --- */
if (DxLib_Init() == -1) // 初期化に失敗したなら
{
return -1; // -1を返す(初期化関数を初期化失敗で終わらせる)
}
/* --- シーン処理の初期化 --- */
if (Scene_class.Scene_Init(TitleScene) == -1) // 初期化に失敗したら
{
return -1; // -1を返す(初期化関数を初期化失敗で終わらせる)
}
return 0; // 諸々の初期化関数の終了(正常終了)
}
/* +++ ゲームの終了処理(ここに諸々の終了処理を集める) +++ */
void Game_End(void)
{
DxLib_End(); // DxLibの終了
return;
}
/* === SceneManager.h === */
#ifndef SCENEMANAGER_H // 2重インクルード防止
#define SCENEMANAGER_H
#include "DxLib.h"
#include "Title.h"
#define GameSceneNumber 4 // ゲームシーンの数
#define SceneChangeInterval 60 // シーン切換のインターバルフレーム
/* --- ゲームシーンの列挙 --- */
enum GameScene
{
TitleScene, // タイトル画面
SelectScene, // キャラセレクト画面
};
/* --- シーンマネージャーのクラス --- */
class SceneManager
{
public:
GameScene NowGameScene; // 現在のシーン
GameScene NextGameScene; // 次のシーン
int SceneChangeFrameCount; // 直前のシーン切換からの経過フレーム
/* --- シーンの初期化関数 --- */
int Scene_Init(GameScene sceneName)
{
SceneChangeFrameCount = 0; // シーン切換からの経過フレームをリセット
/* +++ 指定したシーンの初期化関数を呼び出す +++ */
switch (sceneName)
{
case TitleScene:
/* +++ タイトルシーンの場合 +++ */
if (Title_class.Title_Init() == -1) // タイトルシーンの初期化に失敗したら
{
return -1; // シーンの初期化失敗(-1を返す)
}
break;
case SelectScene:
/* +++ キャラセレクトシーンの場合 +++ */
if (SelectScene_class.SelectScene_Init() == -1) // タイトルシーンの初期化に失敗したら
{
return -1; // シーンの初期化失敗(-1を返す)
}
break;
default:
break;
}
return 0;
}
/* --- シーンの処理を管理する関数 --- */
int Scene_Manage()
{
if (NextGameScene != NowGameScene) // 現在のシーンと次のシーンが異なる(シーンが切り換わる)
{
/* +++ 切り換わり先のシーンに応じて引数を変えてシーン初期化関数を実行 +++ */
switch (NextGameScene)
{
case TitleScene:
/* +++ タイトルシーンの場合 +++ */
/* +++ タイトルシーンを引数にシーンの初期化関数を実行 +++ */
if (Scene_Init(TitleScene) == -1) // シーン初期化に失敗した
{
return -1; // シーンの処理の失敗(-1を返す)
}
break;
case SelectScene:
/* +++ キャラセレクトシーンの場合 +++ */
/* +++ キャラセレクトシーンを引数にシーンの初期化関数を実行 +++ */
if (Scene_Init(SelectScene) == -1) // シーン初期化に失敗した
{
return -1; // シーンの処理の失敗(-1を返す)
}
break;
default:
break;
}
NowGameScene = NextGameScene; // 切換先のシーンを現在のシーンに設定
}
else
{
/* +++ 現在のシーンに応じて引数を変えてシーンの処理関数を実行 +++ */
switch (NowGameScene)
{
case TitleScene:
/* +++ タイトルシーンの場合 +++ */
Title_class.Title_Manage(); // タイトルシーンの処理関数を実行
break;
case SelectScene:
/* +++ キャラセレクトシーンの場合 +++ */
SelectScene_class.SelectScene_Manage(); // キャラセレクトシーンの処理関数を実行
break;
default:
break;
}
SceneChangeFrameCount++; // シーン切換からの経過フレームを1増やす
}
return 0; // シーン処理の管理関数の終了(0を返す)
}
private:
};
extern SceneManager Scene_class; // シーンマネージャー
#endif
/* === Title.h === */
#include "DxLib.h"
#include "Color.h"
#include "SceneManager.h"
/* --- タイトルクラス --- */
class Title
{
public:
/* --- タイトルシーンの初期化関数 --- */
int Title_Init()
{
/* 今後ここに初期化処理を書いていく */
return 0; // タイトルシーンの初期化の終了(0を返す)
}
/* --- タイトルシーンの処理の管理関数 ---- */
void Title_Manage()
{
Title_Process(); // タイトルシーンの処理
Title_Draw(); // タイトルシーンの初期化
return;
}
/* --- タイトルシーンの処理関数 --- */
void Title_Process()
{
/* 何かしらの条件分岐 */
{
// 次のシーンにキャラセレクトシーンを設定
Scene_class.NextGameScene = SelectScene;
}
return;
}
/* +++ タイトルシーンの描画関数 +++ */
void Title_Draw()
{
DrawString(305, 100, "Game Title", Color_class.Color_White);
DrawString(300, 500, "Press Start", Color_class.Color_White);
return;
}
private:
};
extern Title Title_class;
/* === SelectScene.h === */
#include "DxLib.h"
#include "Color.h"
#include "SceneManager.h"
/* --- キャラセレクトシーンクラス --- */
class SelectScene
{
public:
/* --- キャラセレクトシーンの初期化関数 --- */
int SelectScene_Init()
{
/* 今後ここに初期化処理を書いていく */
return 0; // タイトルシーンの初期化の終了(0を返す)
}
/* --- キャラセレクトシーンの処理の管理関数 ---- */
void SelectScene_Manage()
{
SelectScene_Process(); // キャラセレクトシーンの処理
SelectScene_Draw(); // キャラセレクトシーンの初期化
return;
}
/* --- キャラセレクトシーンの処理関数 --- */
void SelectScene_Process()
{
/* 何かしらの条件分岐 */
{
// 次のシーンにタイトルシーンを設定
Scene_class.NextGameScene = TitleScene;
}
return;
}
/* +++ キャラセレクトシーンの描画関数 +++ */
void SelectScene_Draw()
{
DrawString(305, 100, "Character Select", Color_class.Color_White);
return;
}
private:
};
extern SelectScene SelectScene_class;
「C2065 'SelectScene_class':定義されていない識別子です 」といったエラーが出ました。
このエラーが出ている原因は何なのか、どうすれば解決できるかについてお教えいただきたいです。
また、より良い実装の仕方があれば、その方法についても教えていただきたいです。
文章が長く、読みづらいことと思いますが、なにとぞご返信よろしくお願いします。