最終更新 2003 10/10
サンプルのダウンロード → API_Sleep.lzh(42k)
全ソースコード
Sleep 関数
対応しているバージョン
95, 98, Me, NT3.1以降, CE1.0以降, 2000, XP
使用するヘッダとライブラリ
winbase.h
kernel32.lib
|
ゲームでは必ず行わなければならない処理のひとつです。
フレームレートを一定の速度で保つためにも必須です。
処理速度を一定に保つ方法としては、タイマーを使う方法も考えられます。
しかし、ウィンドウズのタイマーは精度が悪くて、タイマーに任せるのは
なかなか厳しいです。
タイマーを使わないとなると、一定の間隔で処理を行うには、設定している
よりも速く処理が済んだ場合、設定している時間に達するまで待たなければ
なりません。
ウィンドウズで一定時間待つには Sleep() 関数を使います。
引数に待つ時間を指定します。
時間はミリ秒単位(1/1000秒)です。
一秒を指定する場合は1000になります。
ゲームセンターにおいてあるビデオゲーム(俗にいうアーケードゲーム)では
1フレーム1/60秒で処理されているそうですが、ミリ秒になおすと
16.66666・・・
(0.0166666・・・秒)割り切れないので17msecってところ
ですかねぇ〜。
※画面全体を1回描画することを1フレームと計測します。
(よくゲームで扱われるFPSは Frame Per Second 一秒間に更新できる
フレーム数を言います。)
実際にゲームを作って動かしてみれば分かるのですが、よほどスペックの
良いマシンでないと、手の込んだ処理を行う時に1フレーム0.02秒弱で
動かすのは不可能に近いです。
DirectDrawを使って、フルスクリーンの排他モードで動かしても
難しいのではないでしょうか・・・。
自分はゲームを作るとき、1フレーム0.05〜0.08秒(50〜80
msec)で動作させてます。
人間の平均的に反応できる反射速度は0.5秒らしいので、それでも十分
だと思います。
(訓練すると0.2秒以下でも反応できるようになるそうですが・・・。)
ウィンドウアプリケーションの場合は、ウィンドウの上でマウスが動いた
だけでも約10msec遅くなります。
メッセージを処理してるからだと思います。
マシンのスペックによると思いますが、メッセージの処理に10msec
かかるというわけです。
で、処理速度を一定にさせるには、画面を描画する前と後で時間を計って
1フレームよりも速いときは、1フレームと同じ速度になるように Sleep()
関数でウェイトをかけます。
1フレームよりも時間がかかってしまった場合はウェイトをかけないように
します。
1フレーム内で画面の描画が完了できれば一定の速度でゲームは進行する
はずです。
1フレーム以上かかってしまったら、動きが重くなるわけです。
動きが重くならないようにするには、1フレーム内で画面の描画を完了できる
ように、できるだけ速く処理できるようなプログラムを組む必要があります。
だいたいの処理の流れを書くとこんな感じです。
//何ミリ秒ごとに処理をするか
BYTE framePerMSec = 100;
//処理開始前の時間
DWORD startTime = GetTickCount();
/*
画面の描画処理とか〜
*/
//処理終了後の時間
DWORD endTime = GetTickCount();
//必要な待ち時間を計算
int wait = framePerMSec - ( endTime - startTime );
//ウェイトをかける
if( wait > 0 ) Sleep( wait );
Sleep() 関数を使わない方法
|