試しに、おでんをY軸で回転させてみよう。
//更新
void Player::Update()
{
transform_.rotate_.y++;
}
ちゃんとUpdate 関数は呼ばれているのに回転しない。
原因はtransform_.Calclation()を呼んでいないから。
どこで呼んだらいいか考えてみよう
1度ずつしか回してないはずなのに回転が速すぎる。
これは、まだFPS(ゲームの更新速度)を調整してないのが原因。
ゲームは60FPS(1秒間に60回画面を更新)が基本だが、現状FPSがどうなってるのか計測してみよう。
文字表示の機能を作ってないので、計測したところで表示できない。
今回はウィンドウのキャプションバー(タイトルバー)に表示する方法を紹介する。
メッセージループの中に次のように書いてみよう。
//メッセージなし
else
{
SetWindowText(hWnd, "test");
//ゲームの処理
//入力情報の更新
Input::Update();
SetWindowTextとは……見ればわかるね。
一秒間の更新回数を調べたいわけだから、時間を計れないと困る。
timeGetTime()関数を使うと、Windowsが起動してからの時間をミリ秒で取得できる。
ためしに表示してみよう。
//インクルード
#include <Windows.h>
#include <stdlib.h>
#include "Engine\Direct3D.h"
#include "Engine\Input.h"
#include "Engine\RootJob.h"
#pragma comment(lib, "winmm.lib")
//定数宣言
const char* WIN_CLASS_NAME = "SampleGame"; //ウィンドウクラス名
const int WINDOW_WIDTH = 800; //ウィンドウの幅
const int WINDOW_HEIGHT = 600; //ウィンドウの高さ
//メッセージなし
else
{
DWORD nowTime = timeGetTime();
char str[16];
wsprintf(str, "%u", nowTime);
SetWindowText(hWnd, str);
プログラムを起動してからの時間を測りたいなら、起動時の時間を覚えておいて、現在との差を表示すればいい。
static DWORD startTime = timeGetTime();
DWORD nowTime = timeGetTime();
char str[16];
wsprintf(str, "%u", nowTime - startTime);
SetWindowText(hWnd, str);
単純に「何回画面を更新したか」を数えたいだけなら、変数を用意して毎フレーム1を足していけばいい。
//メッセージなし
else
{
static DWORD countFps = 0;
static DWORD startTime = timeGetTime();
DWORD nowTime = timeGetTime();
countFps++;
char str[16];
wsprintf(str, "%u", countFps);
SetWindowText(hWnd, str);
実行すると、明らかに1秒間に1000以上の速度で増えていってるのがわかる
1秒間の更新回数を求めたいのだから、1秒経つ(nowTimeとstartTimeの差が1000以上になる)ごとにカウントを0に戻す。
そして、startTimeをその時の時間で上書きすればいい。
static DWORD startTime = timeGetTime();
DWORD nowTime = timeGetTime();
if(nowTime - startTime >= 1000)
{
countFps = 0;
startTime = nowTime;
}
countFps++;
実行すると、だいたい1秒間に何回更新してるかわかってきた(403のマシンだと3000くらい?)
もっと見やすくするために、更新回数を表示するのは1秒に1回(カウントをリセットする直前)にすればいい。
static DWORD startTime = timeGetTime();
DWORD nowTime = timeGetTime();
if(nowTime - startTime >= 1000)
{
char str[16];
wsprintf(str, "%u", countFps);
SetWindowText(hWnd, str);
countFps = 0;
startTime = nowTime;
}
countFps++;
//ゲームの処理
これで現在のFPSが分かった。
画面の更新を1秒間に60回に抑えたい。
逆に言えば、画面の更新を1/60秒に1回に抑えたい。
やり方は単純で「最後に画面を更新してから1/60秒経過していないなら1回休み」にすればいい。
(ちなみに1/60秒は1000/60ミリ秒)
static DWORD countFps = 0;
static DWORD startTime = timeGetTime();
DWORD nowTime = timeGetTime();
static DWORD lastUpdateTime = nowTime;
if(nowTime - startTime >= 1000)
{
char str[16];
wsprintf(str, "%u", countFps);
SetWindowText(hWnd, str);
countFps = 0;
startTime = nowTime;
}
if (nowTime - lastUpdateTime <= 1000.0f / 60)
{
continue;
}
lastUpdateTime = nowTime;
countFps++;
これで、おおよそ60FPSになったはず。
もっと正確に計測することもできると思うが今回は十分でしょう。
場合によってはFPSが60付近にならない人もいるかもしれません。
実はtimeGetTime()という関数は結構乱暴な関数で、正確な時間を返してくれない場合があります。
そこで、下記の2行を追加しておきましょう。
timeBeginPeriod(1);
static DWORD countFps = 0;
static DWORD startTime = timeGetTime();
DWORD nowTime = timeGetTime();
static DWORD lastUpdateTime = nowTime;
timeEndPeriod(1);
これは「この間は、ちゃんと1ミリ秒単位で時間を計測してください」という意味になります。
「timeGetTime」と「timeBeginPeriod」「timeEndPeriod」はセットで覚えておきましょう。