付録2 DxLibテンプレート
付録2 DxLibゲームテンプレート
このテンプレートでは、次の4つの関数を使ってゲームを作ります。
Initialize();
Update();
Draw();
DeltaTime();
Initialize():ゲーム開始時に1回だけ実行するUpdate():入力確認とゲームの更新を行うDraw():画面を描画するDeltaTime():Update()1回分の経過時間を秒で返す
1.ゲームループ
ゲームは、入力・更新・描画を繰り返して動いています。
Initializeを1回実行する
↓
実際に経過した時間を測る
↓
1/60秒分たまっていればUpdateを実行する
↓
Drawで画面を描画する
↓
最初へ戻る
Update()は、ゲーム内部の時間が1/60秒進むたびに実行されます。
処理が遅れて1/60秒が複数回分たまっている場合は、Draw()を行う前にUpdate()を複数回実行します。
2.フレームレート
このテンプレートでは、ゲーム内部の更新回数を1秒間に60回へ固定します。
const int UPDATE_FPS = 60;
const double FIXED_DELTA_TIME = 1.0 / UPDATE_FPS;
DeltaTime()が返す値は、次のとおりです。
1 ÷ 60 = 約0.016666秒
したがって、Update()の中で次のように書くと、1秒間にspeedだけ移動します。
position += speed * DeltaTime();
このテンプレートで固定しているのは、Update()によるゲーム内部の更新間隔です。
Draw()の実行回数は、モニターのリフレッシュレートや処理速度によって変わることがあります。
3.テンプレート
#include "DxLib.h"
// 画面の大きさ
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
// ゲーム内部を1秒間に更新する回数
const int UPDATE_FPS = 60;
// Update1回分の時間
const double FIXED_DELTA_TIME = 1.0 / UPDATE_FPS;
// 長時間処理が止まった場合に、
// 一度に処理する経過時間の上限
const double MAX_FRAME_TIME = 0.25;
// ゲーム開始時に1回だけ実行する
void Initialize(void)
{
// 初期化処理を書く
}
// 入力確認とゲームの更新を行う
void Update(void)
{
// キーボードやマウスの入力処理を書く
// ゲームの更新処理を書く
}
// ゲーム画面を描画する
void Draw(void)
{
// 描画処理を書く
}
// Update1回分の時間を秒で返す
double DeltaTime(void)
{
return FIXED_DELTA_TIME;
}
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
LONGLONG previousTime;
double accumulator;
// ウィンドウモードで起動する
ChangeWindowMode(TRUE);
// 画面の大きさを設定する
SetGraphMode(
SCREEN_WIDTH,
SCREEN_HEIGHT,
32);
// ScreenFlipで垂直同期を待つ
SetWaitVSyncFlag(TRUE);
// DxLibを初期化する
if (DxLib_Init() == -1)
{
return -1;
}
// 描画先を裏画面にする
SetDrawScreen(DX_SCREEN_BACK);
// ゲームを初期化する
Initialize();
// 時間計測を開始する
previousTime = GetNowHiPerformanceCount();
// まだUpdateで処理していない時間
accumulator = 0.0;
// ゲームループ
while (ProcessMessage() == 0)
{
LONGLONG currentTime;
double frameTime;
// ESCキーが押されたら終了する
if (CheckHitKey(KEY_INPUT_ESCAPE) != 0)
{
break;
}
// 現在時刻を取得する
currentTime = GetNowHiPerformanceCount();
// 前回から実際に経過した時間を秒で求める
frameTime =
(currentTime - previousTime) / 1000000.0;
// 次の計測に備えて現在時刻を保存する
previousTime = currentTime;
// 長時間止まった場合は、処理する時間を制限する
if (frameTime > MAX_FRAME_TIME)
{
frameTime = MAX_FRAME_TIME;
}
// 実際に経過した時間をためる
accumulator += frameTime;
// 1/60秒以上たまっている間、ゲームを更新する
while (accumulator >= DeltaTime())
{
Update();
// Updateで処理した時間を引く
accumulator -= DeltaTime();
}
// 裏画面を黒で消す
ClearDrawScreen();
// ゲーム画面を描画する
Draw();
// 裏画面を表画面へ表示する
ScreenFlip();
}
// DxLibを終了する
DxLib_End();
return 0;
}
4.実行確認
プログラムを実行し、次のことを確認してください。
- 800×600の黒いウィンドウが表示される
- ウィンドウがすぐに閉じない
- ESCキーを押すと終了する
- ウィンドウ右上の閉じるボタンでも終了できる
黒いウィンドウが表示されれば、ゲーム制作の準備は完了です。