DXライブラリでゲームの基礎を作ろう

#はじめに

初回から書くのを忘れていたのですが、ここで書く内容は

・C言語を多少できる
・一から3Dゲームを作りたい

方に向けて書く予定です。

#1.DXライブラリの開始設定

今回は**DXライブラリを使う際に必要になる関数たちを取りまとめるクラスを作成**します。
クラスとは簡単に言えば「関数が入る構造体」といえるものです。

##まずは事前の設定から

ではDXライブラリの基本のキ、環境構築をした際にコピペするであろうこちらを用意しました。

```cpp
#include "DxLib.h"

// プログラムは WinMain から始まります
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	if( DxLib_Init() == -1 )		// ＤＸライブラリ初期化処理
	{
		return -1 ;			// エラーが起きたら直ちに終了
	}

	DrawPixel( 320 , 240 , GetColor( 255,255,255 ) ) ;	// 点を打つ

	WaitKey() ;				// キー入力待ち

	DxLib_End() ;				// ＤＸライブラリ使用の終了処理

	return 0 ;				// ソフトの終了 
}
```
https://dxlib.xsrv.jp/dxuse.html
より

こちらを実行すると、画面が真っ黒になって中心に白い点が表示されるでしょう。何かキーを押すと終了となります

では開始前に設定したい内容を決めます。
デフォルトで640x480解像度のフルスクリーンが生成されました。これをカスタムしていきます。
※尚、失敗時に-1でリターンする処理は一度消してしまいます。クラスを作成する際に面倒になる為です。

```cpp
{
		SetOutApplicationLogValidFlag(FALSE);			/*log*/
		SetMainWindowText("game title");				/*タイトル*/
		ChangeWindowMode(TRUE);							/*窓表示*/
		SetUseDirect3DVersion(DX_DIRECT3D_11);			/*directX ver*/
		SetGraphMode(640, 480, 32);						/*解像度*/
		SetUseDirectInputFlag(TRUE);					/*DirectInput使用*/
		SetDirectInputMouseMode(TRUE);					/*DirectInputマウス使用*/
		SetWindowSizeChangeEnableFlag(FALSE, FALSE);	/*ウインドウサイズを手動変更不可、ウインドウサイズに合わせて拡大もしないようにする*/
		SetUsePixelLighting(TRUE);						/*ピクセルライティングの使用*/
		SetFullSceneAntiAliasingMode(4, 2);				/*アンチエイリアス*/
		SetEnableXAudioFlag(TRUE);						/*XAudioを用いるか*/
		Set3DSoundOneMetre(1.0f);						/*3Dオーディオの基準距離指定*/
		SetWaitVSyncFlag(TRUE);							/*垂直同期*/
		DxLib_Init();									/*ＤＸライブラリ初期化処理*/
		SetSysCommandOffFlag(TRUE);						/*タスクスイッチを有効にするかどうかを設定する*/
		SetAlwaysRunFlag(TRUE);							/*background*/
		SetUseZBuffer3D(TRUE);							/*zbufuse*/
		SetWriteZBuffer3D(TRUE);						/*zbufwrite*/
		MV1SetLoadModelPhysicsWorldGravity(-9.8f);		/*重力*/
}
```

自分はこれらを設定しています。他にも設定できる内容はありますがとりあえずこんな感じ。


##DXDrawクラスを作成

さて、DXライブラリでは

・DxLib_Initを呼び出して開始
・DxLib_Endを呼び出してから終わる

必要があるのですが、わざわざ書くのも面倒です。
そこでC++の機能、クラスのコンストラクタ、デストラクタを用いましょう。
コンストラクタ、デストラクタはクラスを生成した際、破棄した際に自動で呼ばれる関数です。自動で呼ばれるため、WinMainに毎回書く必要がなくなります。
以下、DXDrawクラスを用いたコードです。

```cpp
#include "DxLib.h"

//いろいろまとめるクラス
class DXDraw {
public:
	//コンストラクタ
	DXDraw() {
		SetOutApplicationLogValidFlag(FALSE);			/*log*/
		SetMainWindowText("game title");				/*タイトル*/
		ChangeWindowMode(TRUE);							/*窓表示*/
		SetUseDirect3DVersion(DX_DIRECT3D_11);			/*directX ver*/
		SetGraphMode(640, 480, 32);						/*解像度*/
		SetUseDirectInputFlag(TRUE);					/*DirectInput使用*/
		SetDirectInputMouseMode(TRUE);					/*DirectInputマウス使用*/
		SetWindowSizeChangeEnableFlag(FALSE, FALSE);	/*ウインドウサイズを手動変更不可、ウインドウサイズに合わせて拡大もしないようにする*/
		SetUsePixelLighting(TRUE);						/*ピクセルライティングの使用*/
		SetFullSceneAntiAliasingMode(4, 2);				/*アンチエイリアス*/
		SetEnableXAudioFlag(TRUE);						/*XAudioを用いるか*/
		Set3DSoundOneMetre(1.0f);						/*3Dオーディオの基準距離指定*/
		SetWaitVSyncFlag(TRUE);							/*垂直同期*/
		DxLib_Init();									/*ＤＸライブラリ初期化処理*/
		SetSysCommandOffFlag(TRUE);						/*タスクスイッチを有効にするかどうかを設定する*/
		SetAlwaysRunFlag(TRUE);							/*background*/
		SetUseZBuffer3D(TRUE);							/*zbufuse*/
		SetWriteZBuffer3D(TRUE);						/*zbufwrite*/
		MV1SetLoadModelPhysicsWorldGravity(-9.8f);		/*重力*/
	}
	//デストラクタ
	~DXDraw() {
		DxLib_End();	// ＤＸライブラリ使用の終了処理
	}
};


// プログラムは WinMain から始まります
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	DXDraw draw;

	DrawPixel(320, 240, GetColor(255, 255, 255));	// 点を打つ
	WaitKey();					// キー入力待ち
	return 0;					// ソフトの終了 
}
```

クラスを別のヘッダーに分けておけば、サンプル以上にすっきりさせることができました。
やったね！

##よくないね

はい、本当は実体でなしにちゃんと確保すべきです(C++erゴリラに腹筋ボコボコにされる)。破棄を自動でやってくれるスマートポインタを使って小改良します。

```cpp
#include "DxLib.h"
#include<memory>

//いろいろまとめるクラス(ry

// プログラムは WinMain から始まります
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	//コピーしてはいけない場合unique_ptrを使おう
	auto draw = std::make_unique<DXDraw>();
	{
		DrawPixel(320, 240, GetColor(255, 255, 255));	// 点を打つ
		WaitKey();										// キー入力待ち
	}
	return 0;// ソフトの終了 
}
```
基本的にはWinMainの中で完結させるのでunique_ptrを使います。**#includeをお忘れなく**

##まとめ

無駄に長いように見えますが、パーツに分けることで使いまわしがききやすくなります。
とりあえず基礎を固めて次へ行きましょう。

次はエフェクシアの導入を書こうと思います。