C++の勉強しながらDxLibで2Dゲーム作ってみない?(実践編)④

# 今回の目標
今回はせっかく変数や描画関数がだんだん使えるようになってきたので画像の表示をやっていきましょう。
そして前回まで変数に触れてきましたが`定数`の説明もしていきます！
ですがこの定数、実は初回から知らずに使っていたんですよ(*'▽')
ではやっていきましょう！！！

[前回 : C++の勉強しながらDxLibで2Dゲーム作ってみない?(実践編)③](https://qiita.com/mayu___cs/items/1c5ab82de877e5a407a6)

# この記事の対象
・Dxlibを使いゲーム開発をしてみたい方

・C++を始めたばかりの初心者の方で作りながら覚えたい方

・何かしらのライブラリやツールを使ってゲーム開発をしてみたい人方

# これって変数じゃ...?いや定数です
まずは一番最初に書いたこのコードを見てください。

```cpp:main.cpp
#include "DxLib.h"

const char *TITLE = "Untitled";
const int WIN_WIDTH = 960;
const int WIN_HEIGHT = 540;

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
    ChangeWindowMode(true);
    SetWindowSizeChangeEnableFlag(false, false);
    SetMainWindowText(TITLE);
    SetGraphMode(WIN_WIDTH, WIN_HEIGHT, 32);
    SetWindowSizeExtendRate(1.0);
    SetBackgroundColor(35, 35, 35);
    SetDrawScreen(DX_SCREEN_BACK);

    if (DxLib_Init() == -1) { return -1; }

    while (true) {
        ClearDrawScreen();

        ScreenFlip();
        WaitTimer(20);
        if (ProcessMessage() == -1) { break; }
        if (CheckHitKey(KEY_INPUT_ESCAPE) == 1) { break; }
    }

    DxLib_End();
    return 0;
}
```
このコードは一番最初に動作確認で書き、その後これをベースとしてプログラミングしていたものです。
そして`定数`ですがこのコードの最初のほうで既に使われています。
該当コードはこの部分です。

```cpp
const char *TITLE = "Untitled";
const int WIN_WIDTH = 960;
const int WIN_HEIGHT = 540;
```
おいおいおい、変数だわこいつと思った方はおそらく僕の記事から学習していただいている方かと思います。
ですがこれ、実は変数ではなくC++では`定数`というものなんです。

###変数と定数の違い
先ほど定数として紹介したコードですが一部を消すと変数になります。
変数にしてしまったコードはこちらです。

```cpp
char *TITLE = "Untitled";
int WIN_WIDTH = 960;
int WIN_HEIGHT = 540;
```
`const`というワードが消えました。
そう、この`const`というものをつけると変数から定数に変わります。
これは`const修飾子`といい***値の書き換えを禁止する***ものとなります。

### なぜ書き換えを禁止するのか
`const`をつけると書き換えを禁止することはわかった、でもそれ必要...?と感じる方は正直いるかと思います。
ですがこの定数というものはかなり役に立つものとなります。
C++には`ポインタ`というものが存在するのですがおそらくそれを使っているときが一番定数を使っていて幸せを感じる瞬間だと思います。
ですがまだポインタをこの記事では扱っていないので今は画面サイズで考えてみましょう。
今までのコードで画面サイズを設定する前に定数で定義していたコードは以下の部分です。

```cpp
const int WIN_WIDTH = 960;
const int WIN_HEIGHT = 540;
```
そしてこの画面サイズを表している定数、画面の中心を求めたりするときによく使っていましたね。
ですがこの画面サイズを変数で定義してしまうと不意に代入や書き換えを行ってしまったときのバグにつながります。
そしてそのような値の書き換えをしてはいけないものを守るためにあるのがこの`const修飾子(定数)`です。
ですので今はまだあまり必要性を強く感じないかもしれませんが値の書き換えが必要ない変数は定数にすることを強くお勧めします。

# 画像の描画関数
さて、これができるとかなりゲームを作れるようになってきます。
3Dゲームではモデルの読み込みですがUIには画像が使われていたり今回の目標である2Dゲームでは多くの場合キャラクターは画像を使っているはずです。
アニメーションも連番画像を読み込んで順に表示することで動かしたりしています。
そのためゲーム開発での画像の読み込みは欠かせないものとなります。
ですが画像の読み込み、表示はさほど難しくなくこちらも関数を使い表示まで行ってくれます。

### ・LoadGraph関数
画像を表示するにしてもまずは読み込まなければなりません。
そしてその読み込みを可能にするDxLibの関数が`LoadGraph`です。
この関数は以下のように使います。

```cpp
LoadGraph("画像のファイルパス");
```
これだけで画像ファイルをメモリに読み込むことができます。
ですがこれだけでは表示するために読み込みをしているのに表示することができないので以下のように変数で管理します。

```cpp
int character = LoadGraph("画像のファイルパス");
```
この`LoadGraph`という関数は画像を読み込み、読み込んだ画像の識別番号を`int型(整数型)`で返します。
なのでint型変数に代入したり初期化時にこの関数を読み込むことで画像を表示するために使う変数を作ることができます。

### DrawGraph関数
名前でお察しだとは思いますがこちらは読み込んだ画像を表示するための描画関数です。
画像を表示するためにはこの2つをセットで扱います。
そしてこの関数は次のように使います。

```cpp
//画像の読み込み
int character = LoadGraph("ファイルパス");

//画像の描画
DrawGraph(x, y, chatacter, true);
```
引数を見るとLoadGraphで値を受け取った`character`という変数を第3引数にしています。
第4引数にある`true`はその画像を**透過するか**です。
第1,2引数は座標ですので、すなわち変数`character`に入っている識別番号の画像を透過して座標(x, y)に表示するという処理になります。
では実際に画像を表示してみましょう。
おそらく下の図のような階層になっていると思いますので`main.cpp`があるファイルに画像を入れてください。

```:ファイル階層
プロジェクトファイル
   ┣━ .vs
   ┣━ Debug
   ┣━ プロジェクトファイル名 <-このフォルダに入れる
   ┃    ┣━ Debug
   ┃    ┣━ プロジェクトファイル名.vcxproj
   ┃    ┣━ プロジェクトファイル名.filters
   ┃    ┣━ プロジェクトファイル名.user
   ┃    ┣━ Log.txt
   ┃    ┗━ main.cpp
   ┃  
   ┗━ プロジェクトファイル名.sln
```

画像がない方は僕が適当に描いたドット絵でも使ってください。
![player.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390774/8d05a37a-528a-3670-3e05-0739be9fe4f3.png)

画像が用意できたら以下のコードを書いてみてください。
**※このときご自身で画像を用意された方はファイル名を用意した画像の名前にしてください**

```cpp:main.cpp
#include "DxLib.h"
#include <cmath>

const char *TITLE = "Untitled";
const int WIN_WIDTH = 960;
const int WIN_HEIGHT = 540;

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
	ChangeWindowMode(true);
	SetWindowSizeChangeEnableFlag(false, false);
	SetMainWindowText(TITLE);
	SetGraphMode(WIN_WIDTH, WIN_HEIGHT, 32);
	SetWindowSizeExtendRate(1.0);
	SetBackgroundColor(35, 35, 35);
	SetDrawScreen(DX_SCREEN_BACK);

	if (DxLib_Init() == -1) { return -1; }

	int character = LoadGraph("player.png");

	while (true) {
		ClearDrawScreen();

		DrawGraph(50, 50, character, true);

		ScreenFlip();
		WaitTimer(20);
		if (ProcessMessage() == -1) { break; }
		if (CheckHitKey(KEY_INPUT_ESCAPE) == 1) { break; }
	}

	DxLib_End();
	return 0;
}
```

ここまでできたら実行してみましょう。
実行すると以下のようになりますね。
![ウィンドウ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390774/1f43c8be-087c-7988-7ef6-471cccfa3508.jpeg)

表示できましたね！お疲れさまでした！

# 次回
画像の表示までできたら次はアニメーションをやりましょう！
アニメーション、今回ほどじゃないですが割と簡単にできますのでお楽しみに！

# あとがき
そういえばあとがき前回書き忘れてました;;;;;;;;;;;
まぁこんなとこまで見てないとは思いますがw
正直DxLibだけでなくC++も含めて説明しても4回目でここまで進むもんだなぁと思ってます。
今回はてーきゅう見ながら書いてたので一応後日見直して間違えてるところないか確認しておきます...w

### 作者について
詳しくはわんころメソッド();HPにどうぞ(*'▽')

[・わんころメソッド();HP](http://mayu-cs.xyz/)
[・Twitter(まゆC#)](https://twitter.com/mayu___cs)
[・GitHub(まゆC#)](https://github.com/mayu-cs)

#### コミュニティ
Discordで雑談から質問まで様々なチャンネルがあるまゆC#のコミュニティサーバーがあります！
わからないことがあればこちらでもお答えするのでぜひ！
[Discordサーバー : わんころメソッド(雑談);](https://discord.com/invite/TZVTBkk)