Help us understand the problem. What is going on with this article?

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

今回の目標

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

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

この記事の対象

・Dxlibを使いゲーム開発をしてみたい方

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

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

これって変数じゃ...?いや定数です

まずは一番最初に書いたこのコードを見てください。

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;
}

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

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

おいおいおい、変数だわこいつと思った方はおそらく僕の記事から学習していただいている方かと思います。
ですがこれ、実は変数ではなくC++では定数というものなんです。

変数と定数の違い

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

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

constというワードが消えました。
そう、このconstというものをつけると変数から定数に変わります。
これはconst修飾子といい値の書き換えを禁止するものとなります。

なぜ書き換えを禁止するのか

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

const int WIN_WIDTH = 960;
const int WIN_HEIGHT = 540;

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

画像の描画関数

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

・LoadGraph関数

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

LoadGraph("画像のファイルパス");

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

int character = LoadGraph("画像のファイルパス");

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

DrawGraph関数

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

//画像の読み込み
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

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

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

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

次回

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

あとがき

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

作者について

詳しくはわんころメソッド();HPにどうぞ(*'▽')

・わんころメソッド();HP
・Twitter(まゆC#)
・GitHub(まゆC#)

コミュニティ

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

mayu___cs
絵を描くキモオタプログラマーです(*'▽')
http://www.mayu-cs.xyz
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away