Sleep() 関数を使わずに一定の速度で処理を行う
|
最終更新 2003 10/15
サンプルのダウンロード → API_timeGetTime.lzh(43k)
全ソースコード
timeGetTime 関数
対応しているバージョン
95, 98, Me, NT3.1以降, 2000, XP
使用するヘッダとライブラリ
mmsystem.h
winmm.lib
|
時間を計測するには timeGetTime() 関数を使います。
timeGetTime() 関数はウィンドウズを起動してから、現在まで何ミリ秒経過して
いるかを返す関数です。(ミリ秒は1/1000秒です。)
ですから、時間を計測したい処理(画面を描画する等)を実行する前に、あらかじめ
この関数の戻り値を適当な変数に保存しておきます。処理が終了したら、別の変数に
この関数の戻り値を保存します。そうしたら、2番目に保存した変数から1番目に
保存した変数の値を引き算すると、処理にかかった時間を知ることができます。
long startTime = timeGetTime();
/*
いろんな処理〜
*/
long endTime = timeGetTime();
long passTime = endTime - startTime;
passTime に処理にかかった時間がミリ秒で保存されます。
これを利用すれば Sleep() 関数を使わずに、一定の速度で画面を描画する事が
できます。
実際には
1.処理にかかった時間を蓄積するグローバル変数を用意する
2.timeGetTime() で最初の時間を計測
3.処理を実行
4.timeGetTime() で最後の時間を計測
5.最後の時間から最初の時間を引く
6.グローバル変数に5.でかかった時間を足す
7.グローバル変数の値が一定の値以上なら画面を更新
こんな流れで処理を行います。
//グローバル変数宣言
long g_timeCount = 0;
long g_frameRate = 50; //50ミリ秒ごとに画面を更新
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
処理を実行する関数の中
long startTime = timeGetTime();
/*
いろんな処理〜
キー判定とか当たり判定とか
見えない画面に絵を貼り付けたりとか
*/
long endTime = timeGetTime();
long passTime = endTime - startTime;
g_timeCount += passTime;
if( g_timeCount >= g_frameRate )
{
/*
画面を更新
見えない画面で作成した絵をウィンドウに転送する
DirectDraw でいうところのフリップ
*/
g_timeCount = 0;
}
|
ゲームの場合はウィンドウに絵を表示する前に、あらかじめ見えない画面(裏画面)
にキャラクタとか背景とかの絵を貼り付ける処理を行います。
で、裏画面の作業が全て済んでから、裏画面に作った絵をまるごとウィンドウに
転送して画面を更新するわけですが、この画面を更新する作業は g_timeCount の
値が g_frameRate で設定した値以上になるまでは行いません。
それまで、画面上には古い絵が表示されつづけることになります。
見かけ上は Sleep() 関数を使ってウェイトをかけているような状態になります。
Sleep() 関数を使う場合と大きく異なる点は、画面は止まっていても処理は
行われています。
Sleep() 関数は処理そのものを止めてしまうので、キー入力やボタン判定なんかも
全て止まってしまいます。
ですから、Sleep() 関数を使った場合、画面を更新する時間(上のサンプルでは
g_frameRate にあたる)を100ミリ秒くらいの大きめの値に設定すると
「やけに重いなぁ〜」という印象を受ける事になってしまいます。
|