Home | Lesson | Game | Tool | Link

B08.FPS固定

PC性能によってバラバラなFPSを固定します。
ここでは、コンシューマゲームでよくある60FPSに設定します。


インクルードファイル追加
システムのtimerを使用するので、mmsystem.hとwinmm.libを使用します。
#ifdef WIN32
	#include <windows.h>
	#include <mmsystem.h>
	#pragma comment(lib, "winmm.lib")
	#pragma comment(lib, "Irrlicht.lib")
#endif

変数用意
FPSを設定/表示するための変数を用意します。
FPSを60に固定するので、frameに60をセットします。
100にしたい場合は100にセットしてください。
frameBaseは基本的には1000ですが、計算しやすいように3倍の3000にしてあります。
※これにより、取得した値も3倍にする必要があります。
 3倍にしたのは、60FPSの場合キリのよい数字を取得できるようにするためです。

	//FPS設定
	wchar_t tmp[32] = L"";
	u32 fps, lastFPS  = -1;
	u32 frame     = 60;	//設定FPS
	u32 frameBase = 3000/frame;	//更新時間(計算しやすいように3倍)
	u32 lastTime  = 0;		//前回の時間
	u32 errorTime = 0;		//誤差値
	u32 currentTime;		//現在の時間
	u32 pastTime;		//経過時間

メインループ
FPS固定は以下の手順で行います。
1.メインループで経過時間を取得します。
2.経過時間が指定時間を超えていない場合はsleepします。
3.超えている場合は時間を記録し、メイン処理に入ります。

beginScene()、drawAll()、endScene()をループの中に記述します。
これにより、更新してよい場合だけ更新することになります。
	while(device->run())
	{
		currentTime  = timeGetTime();
		pastTime     = (currentTime - lastTime) * 3 + errorTime;
		if(pastTime >= frameBase)
		{
			lastTime  = currentTime;
			errorTime = pastTime % frameBase;
		

			//以下が描画処理のメイン
			driver->beginScene(true,true,0xFF6060FF);

			//シーンの描画
			smgr->drawAll();

			driver->endScene();

		}
		else Sleep(1);

		//FPS取得/表示
		fps = driver->getFPS();
		if(lastFPS != fps)
		{
			swprintf(tmp, 32, L"Irrlicht fps:%d", fps);
			device->setWindowCaption(tmp);
			lastFPS = fps;
		}
	}


FPS固定
FPSを固定すると、意図した通りに動作させることができます。
たとえば、敵をAからBに10秒かけて移動させたいとします。
しかしPCの性能によっては、2秒でBに到達したり20秒たってやっと到達する場合があります。
これを固定させることにより、どのPCでも同じように動作させることが可能になります。

処理に余裕のあるPCの場合は、エフェクトをバリバリ使用するようにしてもよいでしょう。
余裕のないPCには、重い処理のエフェクトを切って、FPSを安定させるという使い方もできます。

FPSの目安としては、60FPSにしておくと丁度よいかもしれません。
せっかくのPCゲームなので100以上にするかは、内容によって決めてみましょう。

ダウンロード
今回作成したファイル一式です。

宿題
1.FPSを120/60/30にして、それぞれ動作の違いがあるか確認してみましょう。