Avance.Lab

コラム

【DXライブラリ】#1.ゲームの基本構造とひな形プログラムの作成【ゲームプログラミング】

公開日:2026.01.30 更新日:2026.01.30

tag: ゲームプログラミング

はじめまして、25年4月に入社したR-Kです!よろしくお願いします!

さて、私は学生時代にプログラミングを学習していましたが、
入社してからは、テスト設計やサーバ構築などの業務に携わっています。

そこで、プログラミングの学習・復習という意味を込めて
DXライブラリというオープンソースのライブラリを使用したゲームプログラミングをしていきます!

第1回となる今回は、DXライブラリの概要と「ゲームの基本構造」について紹介し
DXライブラリを使用したプログラムのひな形を作ることを目的としています。

DXライブラリとは

DXライブラリ(DxLib)は、無料のC++向けゲーム開発用ライブラリです。
DirectXを簡単に扱えるようにしたライブラリとなります。

【補足】DirectXとは?

DirectXとは、Microsoftが開発したWindows向けAPIの総称のことです。
プログラマーがグラフィックスやサウンドなどの処理を行わせたいときに、
ハードウェア(GPUやサウンドカードなど)の制御を代わりに行ってくれる非常に画期的な存在です。
しかし、実装するまでのソースコードは膨大で、開発者に負担がかかってしまう弱点もあります。
(私が以前DirectXを触ったときは、画像を1枚描画するだけで数百行も書いた記憶があります…)

DXライブラリのメリットとして、

  • DirectXの知識が不要で、誰でも簡単に画像の描画や音声再生、入力情報の取得ができる
  • Windows向けGUIアプリケーションが簡単に作れる
  • C++向けだが、C言語の基礎知識だけでもゲームプログラミングに挑戦できる
  • UnityやUnreal Engineなどのゲームエンジンよりも圧倒的に負荷が軽い

などが挙げられます。

デメリットとして、

  • ソースコードのみなので実際のオブジェクトの座標やGUIがわかりにくく、
    イメージが掴みにくい
  • UnityやUnreal Engineではほぼコーディングせずに実装できるゲーム特有の機能があるが、
    DXライブラリでは自分で実装する必要がある(DirectXそのままよりは楽)

などが挙げられます。

DXライブラリではゲームのクオリティを上げるためのコストがかかるため
手軽に「市販化されているゲーム」のようなクオリティを求める方は、
UnityやUnreal Engineなどのゲームエンジンを使うことをおすすめします。

DXライブラリは、以下の人におすすめできます。

  • C/C++の基礎知識でゲームを作ってみたい人
  • プログラミングやコーディングが好きな人
  • 機能を自分の力で実装できたときの達成感を味わいたい人

DXライブラリを使ってみたい、興味があるという方はこちらのリンクをご参照ください。
DXライブラリ配布ページ:https://dxlib.xsrv.jp/index.html

ゲームの基本構造

それでは初めに、ゲームの基本構造について紹介します。

一般的なゲームのプログラムは、以下の図のような順番で処理しています。

主に4つの処理から成り立ち、「入力判定」~「描画処理」がループし続けていることがわかります。

それぞれの処理を詳しくまとめると、以下のようになります。

1. 初期化処理

アプリケーションの初期化や、ゲームに必要なリソース(画像や音楽データなど)を読込む処理です。
規模が大きい3Dゲームや、メモリ効率に配慮したプログラムの場合は、
「初期化処理」以降の、所謂ローディング画面などで
必要になったリソースをその都度読込むことが多いです。

2. 入力判定

プレイヤーからの入力情報(キーボードやコントローラーなどの入力)を判定します。
続く「計算処理」では、入力情報が確定していなければ正確な計算ができないため
順番は必ず「計算処理」の前になります。

3. 計算処理

ゲームシステムを実行する処理です。
プレイヤーからの入力を受けてゲームで必要なほとんどの処理を実行し、内部データを確定させます。

  • 物理演算
  • ゲームオブジェクト(キャラクターやアイテムなど)の座標更新など内部データの更新
  • そのゲーム特有の処理(ステージや敵を生成、ダメージ計算など非常に多岐にわたる)

など、ゲームを成り立たせるための最も重要な部分のため、プログラムの量は多くなります。

4. 描画処理

「計算処理」で最新の状態となった内部データをもとに、画像や3Dモデル、GUIなどを描画します。
また、ここでは内部データを更新してはならず、
「描画処理」は必ず「計算処理」の後に実行する必要があります。

例えば、描画されたあとにゲームオブジェクトの座標を更新していたらどうでしょうか。
ゲームオブジェクトの二次元座標が (X:0, Y:0) の状態で描画しているのに対し、
内部データでは (X:1, Y:0) となってしまうと辻褄が合わなくなってしまいます。
細かな差であっても、バグの発生やそのデバッグ作業が困難になる原因となります。

【補足】有名なゲームでもこうなっているの?

近年の大規模なゲーム(AAAタイトル)やインディーゲームなどの市販化されているゲームでは、
UnityやUnreal Engineまたは専用ゲームエンジンを使用していることが大半です。
その場合はマルチスレッド化して負荷を分散させているので、処理順が変動する場合があります。
しかし、処理順によって不都合が生じないように工夫を凝らしています。
※本記事ではメインスレッドのみで処理するプログラムを紹介しています。

プログラムにしてみる

では、ゲームの基本構造をシンプルなプログラムにしてみます。

今回使用した環境はこちらです。

  • Windows 11
  • Visual Studio 2022
  • C++14
  • DXライブラリ(後ほど使用します)

まずは先ほどの図をそのままプログラムにしてみましょう。

int main(void) {
	// 初期化処理

	/* --- 無限ループ --- */
	while (true) {
		// 入力判定
		// 計算処理
		// 描画処理
	}

	return 0;
}

非常にシンプルなプログラムとなりました。
ですが、このプログラムではコンソール画面が出るだけでゲームらしさは全くありません。

ここからはDXライブラリの関数を使用し、ゲームを作るための土台作りをします。

【補足】プロジェクトの環境構築

ここではプロジェクトにDXライブラリを導入し、GUIアプリの動作にするまでの手順を説明します。

1. DXライブラリを導入する

プロジェクトを作成し、以下の状態からスタートします。

メニューバーの「プロジェクト」を選択し、「(プロジェクト名)のプロパティ」を選択します。

プロジェクトのプロパティ ページが表示されるので、
「構成プロパティ」→「C/C++」 を選択します。

「追加のインクルード ディレクトリ」に、DXライブラリの「LIB」フォルダの絶対パスを入力します。
DXライブラリのダウンロードは、以下のリンクから行えます。
DXライブラリ配布ページ:https://dxlib.xsrv.jp/index.html

続いて、「構成プロパティ」→「リンカー」を選択します。

「追加のライブラリ ディレクトリ」に、
先ほどと同じくDXライブラリの「LIB」フォルダの絶対パスを入力します。

上記の手順でDXライブラリの導入ができました。(設定の適用を忘れずに!)

2. GUIアプリ向けの設定

同じく「構成プロパティ」→「リンカー」の「システム」を選択します。

「サブシステム」を、「コンソール」から「Windows」に変更します。

以上で、プロジェクトの環境構築が完了しました。

今回は、ウィンドウを表示するまでのプログラムを作ります。

#include <DxLib.h>

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {

	/* アプリケーションを初期化 */
	DxLib::SetMainWindowText("SampleProject");		// ウィンドウ名
	DxLib::SetGraphMode(1024, 768, 32);				// ウィンドウサイズを指定
	DxLib::SetWindowSizeExtendRate(1);				// ウィンドウの拡大率
	DxLib::ChangeWindowMode(true);					// ウィンドウモードを設定(TRUE:ウィンドウ, FALSE:フルスクリーン)

	if (DxLib::DxLib_Init() == -1) {				// DxLibの初期化に失敗した
		return 0;
	}

	DxLib::SetDrawScreen(DX_SCREEN_BACK);			// 裏画面描画開始

	/* ゲームリソースを初期化 */

	/* ----------------------- ゲームのループ ----------------------- */
	while (DxLib::ScreenFlip() == 0 &&		// 画面を更新
		   DxLib::ProcessMessage() == 0 &&  // OSからのメッセージを処理
		   DxLib::ClearDrawScreen() == 0) { // 描画を全てリセットする
		/* ここからゲームの処理 → */
		// 入力判定
		// 計算処理
		// 描画処理
		/* ここまでゲームの処理 ← */
	}

	DxLib::DxLib_End();	// DxLib終了

	return 0;
}

いきなりDXライブラリの関数(DxLib::)が出てきて、「よく分からない」という人もいると思いますが、
今回の記事で登場するDXライブラリの関数は、「よく分からない」ままでも問題ありません。

この順番で関数を呼び出すだけでWindowsのGUIアプリケーションが作れ、
DirectXを使用する準備ができるという、
この手軽さがDXライブラリの大きな利点です。

とりあえずゲームを作りたいという人は、
while文の中身を書くだけでゲームプログラミングを始められます。
先ほど図で説明した、「入力判定」「計算処理」「描画処理」の部分です。

/* ----------------------- ゲームのループ ----------------------- */
while (DxLib::ScreenFlip() == 0 &&		// 画面を更新
	   DxLib::ProcessMessage() == 0 &&  // OSからのメッセージを処理
	   DxLib::ClearDrawScreen() == 0) { // 描画を全てリセットする
	/* ここからゲームの処理 → */
	// 入力判定
	// 計算処理
	// 描画処理
	/* ここまでゲームの処理 ← */
}

「よく分からない」状態のままではなく、
DXライブラリの関数を詳しく知りたいという方はこちらをご参照ください。

DXライブラリ 関数リファレンスページ:https://dxlib.xsrv.jp/dxfunc.html

このサイトでは、DXライブラリの主な関数とその使い方が紹介されています。
多種多様な関数があるので、どのように使えるか考えるだけでも楽しいですよ!

DXライブラリを使用する際のひな形を作る

先ほどのプログラムのままでも土台として使えますが、管理しやすいようにクラス化します。
以下がクラス化し、今後DXライブラリを使用する際のひな形としていくプログラムです。

プログラムを見る

#ifndef COMMON_H_DEFINED_	// COMMON_H_DEFINED_ 多重インクルード防止マクロ開始
#define COMMON_H_DEFINED_	// マクロ定義

namespace WINDOW {
	unsigned int WIDTH			 = 1024;	// ウィンドウの横幅
	unsigned int HEIGHT			 = 768;		// ウィンドウの縦幅
	const unsigned int COLOR_BIT = 32;		// カラービット数
}

#endif						// COMMON_H_DEFINED_ 多重インクルード防止マクロ終了

#ifndef GAME_H_DEFINED_		// GAME_H_DEFINED_ 多重インクルード防止マクロ開始
#define GAME_H_DEFINED_		// マクロ定義

/* ゲーム全体を管理するクラス シングルトン */
class Game {
private:
	/// <summary>
	/// コンストラクタ 非公開
	/// </summary>
	Game();

public:
	/// <summary>
	/// デストラクタ
	/// </summary>
	~Game();

	/// <summary>
	/// シングルトン実装静的メソッド
	/// </summary>
	/// <returns>インスタンスへの参照</returns>
	static Game& GetInstance();

	/// <summary>
	/// DXライブラリの初期化処理
	/// </summary>
	/// <returns>TRUE:初期化成功, FALSE:初期化失敗</returns>
	bool Initialize();

	/// <summary>
	/// リソースを解放
	/// </summary>
	void Finalize();

	/// <summary>
	/// メインループを実行
	/// </summary>
	void Run();

};

#endif						// GAME_H_DEFINED_ 多重インクルード防止マクロ終了

// インクルード処理
#include <DxLib.h>
#include "Common.h"
#include "Game.h"

/// <summary>
/// コンストラクタ 非公開
/// </summary>
Game::Game() {

}

/// <summary>
/// デストラクタ
/// </summary>
Game::~Game() {

}

/// <summary>
/// シングルトン実装静的メソッド
/// </summary>
/// <returns>インスタンスへの参照</returns>
Game& Game::GetInstance() {
	static Game instance;
	return instance;
}

/// <summary>
/// DXライブラリの初期化処理
/// </summary>
/// <returns>TRUE:初期化成功, FALSE:初期化失敗</returns>
bool Game::Initialize() {
	/* アプリケーションを初期化 */
	DxLib::SetOutApplicationLogValidFlag(false);							// DxLibのログ消し
	DxLib::SetMainWindowText("SampleProject");								// ウィンドウ名を指定
	DxLib::SetGraphMode(WINDOW::WIDTH, WINDOW::HEIGHT, WINDOW::COLOR_BIT);	// ウィンドウサイズとカラービットを指定
	DxLib::SetWindowSizeExtendRate(1);										// ウィンドウの拡大率を1倍に指定
	DxLib::ChangeWindowMode(true);											// ウィンドウモードを設定(TRUE:ウィンドウ, FALSE:フルスクリーン)

	if (DxLib::DxLib_Init() == -1) {				// DxLibの初期化に失敗した
		return false;
	}

	DxLib::SetDrawScreen(DX_SCREEN_BACK);			// 裏画面描画開始

	return true;
}

/// <summary>
/// リソースを解放
/// </summary>
void Game::Finalize() {
	DxLib::InitFontToHandle();	// フォントハンドルを解放
	DxLib::InitGraph();	        // グラフィックハンドルを解放
	DxLib::InitSoundMem();	    // サウンドハンドルを解放
	DxLib::DxLib_End();	        // DxLib終了
}

/// <summary>
/// メインループを実行
/// </summary>
void Game::Run() {
	/* ゲームリソースを初期化 */

	/* ------------------------- ゲームのループ ------------------------- */
	while (DxLib::ScreenFlip() == 0 &&		// 画面を更新
		   DxLib::ProcessMessage() == 0 &&  // OSからのメッセージを処理
		   DxLib::ClearDrawScreen() == 0) { // 描画を全てリセットする
		/* ここからゲームの処理 → */
		// 入力判定
		// 計算処理
		// 描画処理
		/* ここまでゲームの処理 ← */
	}
}

// インクルード処理
#include <DxLib.h>
#include "Game.h"

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {

    Game& game = Game::GetInstance();

    if (game.Initialize()) {    // DXライブラリの初期化処理
        game.Run();             // ゲームの主な処理
        game.Finalize();        // リソースを解放
    }

    return 0;
}

実行結果

ウィンドウが表示され、アプリケーションが実行されています。

まだ何も描画していないので真っ黒ですが、今後にご期待ください!

【補足】ウィンドウは真っ黒のままだけど…?

ウィンドウは真っ黒ですがプログラムが停止しているわけではありません。
描画を更新するためにプログラムがループし続けています。
 ※例としてモニターのリフレッシュレートが60Hzの環境では60回/秒
今回のプログラムでは1秒間に表示される画像の枚数、所謂 フレームレート(fps)を制御していないので、
使用しているモニターの性能によって、1秒間でプログラムがループする回数が変動します。

終わりに

いかがでしたでしょうか。今回はゲームの基本構造について紹介し、
DXライブラリを使用してウィンドウを表示するプログラムを作成しました。

しばらくは先ほどのひな形に機能を追加していくため地味な画面が多くなりますが、
ゲームを構成する要素を作っていく面白さが少しでも伝わっていれば幸いです!

今後の展望としては、1本のゲームを作るのではなく

  • 知っておくと役に立つ知識や小ネタ
  • DXライブラリの関数紹介
  • あのジャンルのゲームでよく見るシステムを作る

のような、ゲームを作るためのアレやコレについて紹介していきたく思っています。

それでは最後までご覧いただきありがとうございました!

R-K

ゲームとクルマが好き。
ドライブが好きだけど方向音痴なのが最近の悩み。

関連記事