商用のゲームにも色々ありますが、基本的には毎フレーム経過した時間を取得して、
経過時間に応じてゲームを進行させる、という処理を行うことでfpsがどのように
なっても一定の動作をするようにしています
例えば、四角形が画面を左右に跳ね回るだけのプログラムをその手法で組むと以下のようになります
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
LONGLONG NowTime ;
LONGLONG Time ;
float x, add ;
float DeltaTime ;
int FPS ;
int FPSCounter ;
LONGLONG FPSCheckTime ;
// ウインドウモードで起動
ChangeWindowMode( TRUE ) ;
// ScreenFlip を実行しても垂直同期信号を待たない
SetWaitVSyncFlag( FALSE ) ;
// DXライブラリの初期化
if( DxLib_Init() < 0 ) return -1 ;
// 描画先を裏画面にする
SetDrawScreen( DX_SCREEN_BACK ) ;
// 座標を初期化
x = 0.0f ;
// 速度を初期化( 1秒間に移動するドット数 )
add = 200.0f ;
// システム時間を取得しておく
Time = GetNowHiPerformanceCount() ;
// 最初の経過時間は仮に 0.000001f 秒にしておく
DeltaTime = 0.000001f ;
// FPS計測関係の初期化
FPSCheckTime = GetNowHiPerformanceCount() ;
FPS = 0 ;
FPSCounter = 0 ;
// メインループ
while( ProcessMessage() == 0 )
{
// 経過時間を考慮した移動( DeltaTime を掛ける )
x += add * DeltaTime ;
if( x < 0.0f )
{
x = 0.0f ;
add = -add ;
}
if( x > 640.0f )
{
x = 640.0f ;
add = -add ;
}
// 画面のクリア
ClearDrawScreen() ;
// 四角形の描画
DrawBox( ( int )x, 240 - 32, ( int )x + 64, 240 + 32, GetColor( 255,255,255 ), TRUE ) ;
// FPSの描画
DrawFormatString( 0, 0, GetColor( 255,255,255 ), "FPS:%d", FPS ) ;
// 裏画面の内容を表画面に反映
ScreenFlip() ;
// 現在のシステム時間を取得
NowTime = GetNowHiPerformanceCount() ;
// 前回取得した時間からの経過時間を秒に変換してセット
// ( GetNowHiPerformanceCount で取得できる値はマイクロ秒単位なので 1000000 で割ることで秒単位になる )
DeltaTime = ( NowTime - Time ) / 1000000.0f ;
// 今回取得した時間を保存
Time = NowTime ;
// FPS関係の処理( 1秒経過する間に実行されたメインループの回数を FPS とする )
FPSCounter ++ ;
if( NowTime - FPSCheckTime > 1000000 )
{
FPS = FPSCounter ;
FPSCounter = 0 ;
FPSCheckTime = NowTime ;
}
}
// DXライブラリの後始末
DxLib_End() ;
// ソフトの終了
return 0 ;
}
移動速度が一定であることが分かるように ScreenFlip で垂直同期信号を待たない設定( SetWaitVSyncFlag( FALSE ); )にして、
あと FPS表示の処理も入っています
1フレームの経過時間の計測には GetNowCount よりも1000倍精度が高い時間を取得できる GetNowHiPerformanceCount を使用します
( GetNowCount はミリ秒( 1/1000秒 )単位なのに対して、GetNowHiPerformanceCount はマイクロ秒( 1/1000000秒 )単位です )
1フレームの経過時間は変数 DeltaTime に代入するようにしていて、この値に応じて四角形の移動距離が変わるように
なっています( 1フレームの経過時間が長ければ一度に沢山移動して、短ければ移動距離も短くなる )
x += add * DeltaTime ; // ←上記プログラムのこの部分です
60fps などの決め打ちの場合は『1秒間待つ』という処理も 60回メインループが実行されるのを待つ
という処理となりますが、上記のような処理の場合は毎フレームの DeltaTime の値をカウンターの変数に
+= で加算していって、カウンター用変数の値が 1.0f を超えたら1秒経過したと判断するような処理になります