チュートリアル : ゲーム開発用フレームワーク NFrame

チュートリアル : ゲーム開発用フレームワーク NFrame

ゲーム開発用フレームワーク NFrame Topへ

目次

クラス図
ウィンドウの表示
シーンの管理
オブジェクトの管理
コンポーネントの管理

クラス図

uml

ウィンドウの表示

手順

1, GameBaseクラスを継承したクラスを生成する
2, グローバルで1のクラスのインスタンスを生成する

GameBaseクラス

/**
* @brief ゲーム基底クラス
*/
class GameBase
{
public:
/**
 * @brief コンストラクタ
*/
GameBase();

/**
 * @brief デストラクタ
*/
virtual ~GameBase();

/**
* @brief 共通の初期化
* @return 成功(true) 失敗(false)
*/
bool InitCom();

/**
* @brief 共通の更新
*/
void UpdateCom();

/**
* @brief 共通の描画
*/
void DrawCom();

/**
* @brief ログ出力フラグの取得
* @return ログ出力フラグ
*/
virtual bool GetLogFlag() const { return false; }

/**
* @brief ウィンドウ名の取得
* @return ウィンドウ名
*/
virtual std::string GetWindowName() { return "NFrame App"; }

/**
* @brief 画面横幅の取得
* @return 画面横幅
*/
virtual std::int32_t GetDispW() const { return 1280; }

/**
* @brief 画面縦幅の取得
* @return 画面縦幅
*/
virtual std::int32_t GetDispH() const { return 720; }

/**
* @brief 色深度の取得
* @return 色深度
*/
virtual std::int32_t GetColorBitDepth() const { return 16; }

/**
* @brief ウィンドウモードフラグの取得
* @return ウィンドウモードフラグ
*/
virtual bool GetWindowModeFlag() const { return true; }

/**
* @brief 3D使用フラグの取得
* @return 3D使用フラグ
*/
virtual bool GetUse3DFlag() const { return false; }

/**
* @brief フレームレートの取得
* @return フレームレート
*/
float GetFPS() const { return _fps; }

/**
 * @brief 固定フレームレートの取得
 * @return 固定フレームレート
*/
virtual std::int32_t GetFixedFPS() const { return 60; }

/**
* @brief インスタンスの取得
* @return インスタンス
*/
static GameBase& GetInstance() { return *_instance; }

protected:
/**
* @brief 各初期化
* @return 成功(true) 失敗(false)
*/
virtual bool Init() { return true; }

/**
* @brief 各更新
*/
virtual void Update() {}

/**
* @brief 各描画
*/
virtual void Draw() {}

private:
/**
* @brief FPS制御
*/
void FPSManager();

//インスタンス
static GameBase* _instance;
//フレームカウント
int _frameCount;
//最初のフレームの時間
int _startFPSTime;
//フレームレート
float _fps;
};

ウィンドウのサイズ等は、対応したメンバ関数をオーバーライドする事で設定出来ます。
bool GetLogFlag() : DXライブラリで出力されるログを出力するか設定出来ます。
std::string GetWindowName() : ウィンドウ名を設定出来ます。
std::int32_t GetDispW():ウィンドウの横幅を設定出来ます。
std::int32_t GetDispH():ウィンドウの縦幅を設定出来ます。
std::int32_t GetColorBitDepth():色深度を設定できます。
bool GetWindowModeFlag():ウィンドウモードを設定できます。
bool GetUse3DFlag():3Dを使用するか設定出来ます。
std::int32_t GetFixedFPS():FPSを設定出来ます。

最低限のコード

下記のコードをソースファイルに記述して実行すると、1280×720のウィンドウが表示されます。

#include "NFrame.h"
class SampleGame : public NFrame::GameBase{};
SampleGame gSampleGame;

シーンの管理

手順

1, SceneBaseクラスを継承したクラスを生成する
2-1, 登録するなら1で生成したクラスのインスタンスを生成し、SceneManagerクラスのAddSceneで登録する
2-2, 除外するなら登録しているシーンのアドレスを取得し、SceneManagerクラスのRemoveSceneで除外する

SceneBaseクラス

/**
* @brief シーンの基底クラス
*/
class SceneBase
{
public:
/**
* @brief コンストラクタ
*/
SceneBase();

/**
* @brief デストラクタ
*/
virtual ~SceneBase();

/**
* @brief 共通の初期化
* @return 成功(true) 失敗(false)
*/
bool InitCom();

/**
* @brief 共通の更新
*/
void UpdateCom();

/**
* @brief 共通の描画
*/
void DrawCom();

/**
* @brief オブジェクトの取得
* @param[in] オブジェクト
* @return オブジェクト
*/
template
T* GetObjects(const T&)
{
for (auto& obj : _objects)
{
if (typeid(*obj).name() == typeid(T).name())
{
return static_cast(obj);
}
}

return nullptr;
}

protected:
/**
* @brief 初期化
* @return 成功(true) 失敗(false)
*/
virtual bool Init();

/**
* @brief 各更新
*/
virtual void Update() {}

/**
* @brief 各描画
*/
virtual void Draw() {}

/**
* @brief オブジェクトの追加
* @param[in] obj オブジェクト
*/
void AddObject(ObjectBase& obj);

/**
* @brief オブジェクトの除外
* @param[in] obj オブジェクト
*/
void RemoveObject(ObjectBase& obj);

private:
/**
* @brief 更新前処理
*/
void InitUpdate();

//オブジェクト
std::list< ObjectBase*> _objects;
//除外オブジェクト
std::list< ObjectBase*> _removeObjects;
//追加オブジェクト
std::list< ObjectBase*> _addObjects;
};
                    
                    

下記をオーバーライドしてお使いください。
bool Init() : シーン登録時に一度だけ呼ばれます。
void Update() : 毎フレーム(更新時)に呼ばれます。
void Draw() : 毎フレーム(描画時)呼ばれます。

サンプルコード

下記のコードはタイトルシーンでQキーを押すと、ゲームシーンへ遷移するものです。

#include "NFrame.h"


////////////////////シーン関係ここから////////////////////

/**
 * @brief ゲームシーンクラス
*/
class SceneGame : public NFrame::SceneBase
{
public:
	/**
	* @brief 描画
	*/
	void Draw() override;
};

/**
 * @brief 描画
*/
void SceneGame::Draw()
{
	//画面左上に「Game」と描画する
	DrawString(50, 50, "Game", GetColor(255, 255, 255));
}

/**
 * @brief タイトルシーンクラス
*/
class SceneTitle : public NFrame::SceneBase
{
public:
	/**
	 * @brief 更新
	*/
	void Update() override;

	/**
	 * @brief 描画
	*/
	void Draw() override;
};

/**
 * @brief 更新
*/
void SceneTitle::Update()
{
	//Qキーを押した瞬間に
	if (NFrame::Input::GetInstance().IsKeyDown(KEY_INPUT_Q))
	{
		//ゲームシーンを登録する
		//登録したシーンが処理される
		NFrame::SceneManager::GetInstance().AddScene(*new SceneGame);

		//自身(タイトルシーン)を除外する
		//除外したシーンは処理されない
		NFrame::SceneManager::GetInstance().RemoveScene(*this);
	}
}

/**
 * @brief 描画
*/
void SceneTitle::Draw()
{
	//画面左上に「Title」と描画する
	DrawString(50, 50, "Title", GetColor(255, 255, 255));
}

////////////////////シーン関係ここまで////////////////////


////////////////////ゲーム関係ここから////////////////////

/**
 * @brief サンプルゲームクラス
*/
class SampleGame : public NFrame::GameBase
{
public:
	/**
	 * @brief 初期化
	 * @return 成功(true) 失敗(false)
	*/
	bool Init() override;
};

/**
 * @brief 初期化
 * @return 成功(true) 失敗(false)
*/
bool SampleGame::Init()
{
	//タイトルシーンを登録する
	//登録したシーンが処理される
	NFrame::SceneManager::GetInstance().AddScene(*new SceneTitle);

	return true;
}

//グローバルでサンプルクラスのインスタンスを生成
SampleGame gSampleGame;

////////////////////ゲーム関係ここまで////////////////////


                

オブジェクトの管理

手順

1, ObjectBaseクラスを継承したクラスを生成する
2-1, シーンに追加するなら1で生成したクラスのインスタンスを生成し、AddObject関数で登録する
2-2, シーンから除外するなら追加しているオブジェクトのアドレスを取得し、RemoveObject関数で除外する

ObjectBaseクラス

/**
 * @brief オブジェクト基底クラス
 */
class ObjectBase
{
public:
/**
* @brief コンストラクタ
*/
ObjectBase();

/**
* @brief デストラクタ
*/
virtual ~ObjectBase();

/**
* @brief 共通の初期化
* @return 成功(true) 失敗(false)
*/
bool InitCom();

/**
* @brief 共通の更新
*/
void UpdateCom();

/**
* @brief 共通の描画
*/
void DrawCom();

/**
* @brief コンポーネントの取得
* @param[in] コンポーネント
* @return コンポーネント
*/
template
T* GetComponent(const T&)
{
for (auto& comp : _components)
{
if (typeid(*comp).name() == typeid(T).name())
{
return static_cast(comp);
}
}

return nullptr;
}

protected:
/**
* @brief 各初期化
* @return 成功(true) 失敗(false)
*/
virtual bool Init() { return true; }

/**
* @brief 各更新
*/
virtual void Update() {}

/**
* @brief 各描画
*/
virtual void Draw() {}

/**
* @brief コンポーネントの追加
* @param[in] comp コンポーネント
*/
void AddComponent(ComponentBase& comp);

/**
* @brief コンポーネントの除外
* @param[in] comp コンポーネント
*/
void RemoveComponent(ComponentBase& comp);

private:
/**
* @brief コンポーネントの更新
*/
void UpdateComponent();

/**
* @brief コンポーネントの描画
*/
void DrawComponent();

/**
* @brief コンポーネントの更新前の初期化
*/
void InitUpdateComponent();

//コンポーネント
std::list< ComponentBase*> _components;
//追加するコンポーネント
std::list< ComponentBase*> _addComponents;
//除外するコンポーネント
std::list< ComponentBase*> _removeComponents;
//コンポーネントは更新中か
bool _isCompUpdate;
};

下記をオーバーライドしてお使いください。
bool Init() : シーン登録時に一度だけ呼ばれます。
void Update() : 毎フレーム(更新時)に呼ばれます。
void Draw() : 毎フレーム(描画時)呼ばれます。

サンプルコード

下記のコードは、タイトルシーンでQキーを押すとゲームシーンへ遷移し、ゲームシーンで半径10の赤い円を描画するものです。
赤い円がゲームオブジェクトです。

#include "NFrame.h"


////////////////////オブジェクト関係ここから////////////////////

/**
 * @brief サンプルオブジェクトクラス
*/
class SampleObject : public NFrame::ObjectBase
{
public:
	/**
	 * @brief 描画
	*/
	void Draw() override;
};

/**
 * @brief 描画
*/
void SampleObject::Draw()
{
	//画面左上に半径10の赤い円を描画する
	DrawCircle(100, 100, 10, GetColor(255, 0, 0));
}

////////////////////オブジェクト関係ここまで////////////////////


////////////////////シーン関係ここから////////////////////

/**
 * @brief ゲームシーンクラス
*/
class SceneGame : public NFrame::SceneBase
{
public:
	/**
	 * @brief 初期化
	 * @return 成功(true) 失敗(false)
	*/
	bool Init() override;

	/**
	* @brief 描画
	*/
	void Draw() override;
};

/**
 * @brief 初期化
 * @return 成功(true) 失敗(false)
*/
bool SceneGame::Init()
{
	//ゲームシーンにオブジェクトを追加する
	AddObject(*new SampleObject);

	return true;
}

/**
 * @brief 描画
*/
void SceneGame::Draw()
{
	//画面左上に「Game」と描画する
	DrawString(50, 50, "Game", GetColor(255, 255, 255));
}

/**
 * @brief タイトルシーンクラス
*/
class SceneTitle : public NFrame::SceneBase
{
public:
	/**
	 * @brief 更新
	*/
	void Update() override;

	/**
	 * @brief 描画
	*/
	void Draw() override;
};

/**
 * @brief 更新
*/
void SceneTitle::Update()
{
	//Qキーを押した瞬間に
	if (NFrame::Input::GetInstance().IsKeyDown(KEY_INPUT_Q))
	{
		//ゲームシーンを登録する
		//登録したシーンが処理される
		NFrame::SceneManager::GetInstance().AddScene(*new SceneGame);

		//自身(タイトルシーン)を除外する
		//除外したシーンは処理されない
		NFrame::SceneManager::GetInstance().RemoveScene(*this);
	}
}

/**
 * @brief 描画
*/
void SceneTitle::Draw()
{
	//画面左上に「Title」と描画する
	DrawString(50, 50, "Title", GetColor(255, 255, 255));
}

////////////////////シーン関係ここまで////////////////////


////////////////////ゲーム関係ここから////////////////////

/**
 * @brief サンプルゲームクラス
*/
class SampleGame : public NFrame::GameBase
{
public:
	/**
	 * @brief 初期化
	 * @return 成功(true) 失敗(false)
	*/
	bool Init() override;
};

/**
 * @brief 初期化
 * @return 成功(true) 失敗(false)
*/
bool SampleGame::Init()
{
	//タイトルシーンを登録する
	//登録したシーンが処理される
	NFrame::SceneManager::GetInstance().AddScene(*new SceneTitle);

	return true;
}

//グローバルでサンプルクラスのインスタンスを生成
SampleGame gSampleGame;

////////////////////ゲーム関係ここまで////////////////////

コンポーネントの管理