DXライブラリを利用したサンプルプログラム

<!----------------------------------------------------------------------------------------------------------------------------------->
## [1.]概要
<!----------------------------------------------------------------------------------------------------------------------------------->

### [1-1.]作業目的

DXライブラリを利用してサンプルページを表示します。

### [1-2.]環境・前提条件

本件手順では、以下Windows環境にMicrosoft Visual Studioがインストールされている前提とします。

- エディション：Microsoft Windows 10 Pro
- システムの種類：64 ビット オペレーティング システム、x64 ベース プロセッサ
- バージョン：22H2
- OSビルド 19045.3693
- エクスペリエンス：Windows Feature Experience Pack 1000.19053.1000.0
- Microsoft Visual Studio Community 2022 (64 ビット) - Current Version 17.8.1
- ＤＸライブラリ Windows版 VisualStudio( C++ )用(Ver3.24d)
- (2023年11月25日現在)

### [1-3.]参考ページ

- 公式ページ
    - [ＤＸライブラリ置き場](https://dxlib.xsrv.jp/)
    - [Visual Studio Community 2022 を使用した場合のＤＸライブラリの使い方](https://dxlib.xsrv.jp/use/dxuse_vscom2022.html)
    - [ＤＸライブラリ　サンプルプログラム](https://dxlib.xsrv.jp/dxprogram.html)
- FPS処理
    - [3.14章 特定のFPSで動作させる方法](https://dixq.net/g/03_14.html)
- Qiita情報(初期設定)
    - [動かして学ぶDXライブラリ入門](https://qiita.com/yagiri000/items/597456ba8ba8435f1e01)
    - [DXライブラリによるゲーム作成 - Qiita](https://qiita.com/nekoshiki0904/items/7a948220da0ac6f1677f)
    - [【C++】横スクロールゲームを作ってみる【準備編】](https://qiita.com/RINO_001/items/1c6323d3d2c89a09578a)
    - [DXライブラリを使って学ぶ[入門編]](https://qiita.com/kapiba-ra/items/cdef77927af2fcbcd8e0)
- Qiita情報(DXライブラリ関数)
    - [DXライブラリでゲーム開発するための、初めにやっておくべき初期設定10選 #ゲーム制作 - Qiita](https://qiita.com/AioiLight/items/7bfbcd4f0ce786a9acc9)
    - [最低限これだけ知ってればゲームが作れるDXライブラリ関数集](https://qiita.com/GandT/items/ec6e12bcacf7c66c315e)
- DXライブラリサンプルプログラム
    - [新・C言語 ～ゲームプログラミングの館～ [DXライブラリ]](https://dixq.net/g/index.html)
    - [ゲームプログラム・サンプルプログラム集](https://wasyahogame.ifdef.jp/)
- DXライブラリ紹介動画
	- [DXライブラリの環境構築](https://www.youtube.com/watch?v=PRadR7oYsqE)

<!----------------------------------------------------------------------------------------------------------------------------------->
## [2.]DXライブラリ準備
<!----------------------------------------------------------------------------------------------------------------------------------->

下記ページから、DXライブラリの設定準備を進めてください。
- [Visual Studio Community 2022 を使用した場合のＤＸライブラリの使い方](https://dxlib.xsrv.jp/use/dxuse_vscom2022.html)
- 以後はプロジェクト名を「dxtest」、ソース名を「dxtest.cpp」として説明します。

<!----------------------------------------------------------------------------------------------------------------------------------->
## [3.]サンプルプログラムの実装
<!----------------------------------------------------------------------------------------------------------------------------------->

[手順1.]背景画の用意
dxtest.exeと同じディレクトリに「bmp」フォルダを用意し、そのフォルダ内に「back.bmp」というサイズ「1024x768」のBMP画像形式のファイルを配置します。
以下サイズ「1024x768」であるJPEG形式の画像を用意していますが、以下の画像を「bmp形式」に変換してフォルダに画像を配置してください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77425/38d1ed82-2a9d-bff7-f643-15395de4692f.jpeg" width=50%>

[手順2.]ソースの作成

以下のソースについてコピー＆ペーストします。
保存する場合にはテキストファイルを以下の形式としています。

(テキストファイルの仕様)
- 改行コード：SJIS
- 改行コード：CR+LF

<details><summary>dxtest.cpp</summary><div>

```cpp

/* ---------------------------------------------------------------------------------------------- 
 * 
 * プログラム概要   ： DXライブラリサンプル表示
 * バージョン       ： 1.0.0.1
 * プログラム名     ： dxtest.exe
 * ファイル名       ： dxtest.cpp
 * 処理概要         ： メイン処理
 * Ver1.0.0.0作成日 ： 2023/09/09 14:27:05
 * 最終更新日       ： 2024/07/07 14:33:40
 * 
 * Copyright (c) 2023-2023 Techmilestone, All rights reserved.
 * 
 * ---------------------------------------------------------------------------------------------- */

/*  ----------------------------------------
 * 
 * 更新履歴： 
 * 1.0.0.0 ： 2023/09/09 14:27:05 ： 初版作成
 * 1.0.0.1 ： 2024/07/07 14:33:40 ： SetDoubleStartValidFlagを追加、誤字修正
 * 
 *  ---------------------------------------- */

#include "DxLib.h"

// ----------------------------------------
// グローバル変数定義
// ----------------------------------------

	// ----------------------------------------
	// 変数初期化(フレーム処理)
	// ----------------------------------------

	// フレーム処理用定数
	static const int SAMPLE_FRAME_COUNT = 60;   // フレームのサンプル数
	static const int FPS                = 60;   // 想定のFPS値 (待ち時間の算出用)

	// FPS算出用変数(フレーム定義)
	static int frame_count;                     // サンプルフレームのカウンタ数
	static int total_frame_count;               // 処理したフレームの合計数

	// FPS算出用変数(時間定義)
	static int checkpoint_time;                 // 定点時刻(チェックポイントごとの時刻)
	static int wait_time;                       // 待ち時間(Sleep関数を利用するために単位はミリ秒)

	// FPS算出用変数(FPS数)
	static float ave_fps;                       // 実測のFPS値

	// ----------------------------------------
	// 変数初期化(マウス処理)
	// ----------------------------------------

	// マウス処理情報
	static int msx;                     // X座標
	static int msy;                     // Y座標
	static int get_mouse_input;         // マウスの押した状態取得
	static unsigned int get_button[8];  // ボタンの押した状態
	static int wheel_rot_vol;           // ホイールの回転量

	// ----------------------------------------
	// 変数初期化(画像処理)
	// ----------------------------------------

	// 画像ハンドル
	static int pic_handle;              // 背景用画像

// ----------------------------------------
// フレーム初期化
// ----------------------------------------
int WindowFrameInit(){

	// Log.txtの出力抑止
	SetOutApplicationLogValidFlag(FALSE);

	// ウインドウモードにする
	// DxLib_Initより前に行う
    if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK ) {

		// 異常終了
		return -1;

	}

	// ウィンドウサイズ変更
	SetGraphMode( 1024 , 768 , 32 );
	SetWindowSize( 1024 , 768 );

	// ウインドウがアクティブではない状態でも処理を続行する
 	SetAlwaysRunFlag(TRUE);

	// 2つ以上同時に起動できるかどうかを設定する
 	SetDoubleStartValidFlag(TRUE);

	// マウス表示オン
    SetMouseDispFlag(TRUE);

	// 正常終了
	return 0;

}

// ----------------------------------------
// DX表示ライブラリ初期化
// ----------------------------------------
int CustomDxlibInit(){

	// DXライブラリ初期化
	if (DxLib_Init() != 0){

		// 異常終了
		return -1;

	}

	// 描画先を裏画面に設定
	SetDrawScreen(DX_SCREEN_BACK); 

	// 画像ハンドル
	pic_handle = LoadGraph("bmp/back.bmp"); // 画像のロード

	// 正常終了
	return 0;

}

// ----------------------------------------
// DX表示ライブラリ終了処理
// ----------------------------------------
void CustomDxlibEnd(){

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

}

// ----------------------------------------
// Fps算出処理の初期化
// ----------------------------------------
void FpsParamInit(){

	// 変数初期化
	ave_fps           = 0;    // ave_fps初期化
	frame_count       = 0;    // frame_count初期化
	total_frame_count = 0;    // total_frame_count初期化

	// 最初フレームの「定点時刻(checkpoint_time)」定義
	checkpoint_time = GetNowCount();

}

// ----------------------------------------
// 定点時刻(checkpoint_time)の更新、平均Fps算出
// ----------------------------------------
void FpsUpdate(){

	// 変数定義
	int tmp_now_time;    // 現在時刻

	// サンプルフレーム数に達した場合の内部処理
	// 「定点時刻(checkpoint_time)」の更新、「平均ave_fps」算出
	if( frame_count == SAMPLE_FRAME_COUNT ){ 

		// 現在の時間の取得
		tmp_now_time = GetNowCount();

		// 「平均ave_fps」算出処理
		ave_fps = (float)SAMPLE_FRAME_COUNT*1000.f / (tmp_now_time - checkpoint_time);

		// 「フレームのカウンタ数」の初期化
		frame_count = 0;

		// SAMPLE_FRAME_COUNTごとに「定点時刻」を更新
		checkpoint_time = tmp_now_time;

	}

	// 「フレームのカウンタ数」の加算
	frame_count++;

	// 「合計フレームのカウンタ数」の加算
	total_frame_count++;

}

// ----------------------------------------
// FPSウエイト処理
// ----------------------------------------
void FpsWait(){

	// 現在時刻と「定点時刻(checkpoint_time)」との差分時間を算出
	// それから待ち時間(wait_time)を算出
	wait_time = ( frame_count*1000 / FPS ) - (GetNowCount() - checkpoint_time); // frame_countからの理論時刻と実機からの現在時間との差分を算出する

	// ウエイト処理
	if( wait_time > 0 ){
		Sleep(wait_time); // wait_timeの時間(ミリ秒)だけ待機を行う
	}

}

// ----------------------------------------
// マウス状態の取得
// ----------------------------------------
void GetMouseInfo(){

	// マウス情報取得
	GetMousePoint( &msx, &msy );                       // マウスの位置取得
	get_mouse_input = GetMouseInput();                 // マウスの押した状態取得
	for(int but_num = 0; but_num < 8; but_num++){      // マウスのキーは最大8個まで確認可能
		get_button[but_num] = 0;
		if( (get_mouse_input & 1 << but_num ) != 0 ){ 
			get_button[but_num]++;                     // 押されていたらカウントアップ
		}else{
			get_button[but_num] = 0;                   // 押されてなかったら0
		}
	}

	// ホイール回転量取得
	wheel_rot_vol = GetMouseWheelRotVol() ;

}

// ----------------------------------------
// 表示処理
// ----------------------------------------
void CustomDxlibDraw(){

	// 画面を消す
	ClearDrawScreen();

	// 背景表示
	DrawGraph( 0, 0, pic_handle, TRUE );

	// 文字列表示
	DrawFormatString(  5,   0, GetColor(255,255,255), "X=%4d Y=%3d B[0]=%d B[1]=%d wheel_rot_vol=%d", msx, msy, get_button[0], get_button[1], wheel_rot_vol);
	DrawFormatString(  5,  17, GetColor(255,255,255), "実測FPS値                    %.1f", ave_fps);
	DrawFormatString(  5,  34, GetColor(255,255,255), "処理したフレーム数           %10d", total_frame_count);
	DrawFormatString(  5,  51, GetColor(255,255,255), "定点時刻(CheckPointTime)     %10d", checkpoint_time);
	DrawFormatString(  5,  68, GetColor(255,255,255), "待ち時間(wait_time：ミリ秒)  %10d", wait_time);
	DrawFormatString(  5, 200, GetColor(255,255,255), "テスト文字列");

	// 裏画面を表画面に反映
	ScreenFlip();

}

// ----------------------------------------
// メイン処理
// ----------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){

	// ----------------------------------------
	// 事前処理
	// ----------------------------------------

	// Windows画面の事前処理
	if (WindowFrameInit() != 0){

		// ダイアログの出力
		MessageBox( NULL, "異常終了 ChangeWindowMode", "警告", MB_OK );
		return -1;

	}

	// DXライブラリ初期化
	if (CustomDxlibInit() != 0){    

		// ダイアログの出力
		MessageBox( NULL, "異常終了 DxLib_Init", "警告", MB_OK );
		return -1;

	}

	// FPS処理初期化
	FpsParamInit();

	// ----------------------------------------
	// メイン処理(ループ処理)
	// ----------------------------------------

	// 終了処理がされるまで、ループ処理
	while( ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0 ){

		// 関数処理
		FpsUpdate();       // checkpoint_time更新、平均Fps算出
		GetMouseInfo();    // マウス情報取得
		CustomDxlibDraw(); // 表示処理
		FpsWait();         // ウエイト処理

	}

	// ----------------------------------------
	// 終了処理
	// ----------------------------------------

	// DXライブラリ終了処理
	CustomDxlibEnd();

	// 正常終了
	return 0;

}

/* ---------------------------------------------------------------------------------------------- 
 * ソース終了
 * ---------------------------------------------------------------------------------------------- */

```

</div></details>


[手順3.]ソースのビルドを行う。

Visual Studio Communityを利用してビルドしてください。

以上