実装方法はいろいろあるだろうけど、俺は
[1]内部処理
[2]T>tなら[3A]へ、それ以外なら[3B]へ
[3A]描画して t ← 描画にかかった時間 (→[4]へ)
[3B]t ← t - T (→[4]へ)
[4]1に戻ってループ
こんな感じでやってる。T=18〜19msぐらいがいいと思う。
前回の描画である一定以上時間がかかったら、超えた分がチャラになるまで
以降の描画をとばすだけ。
んじゃ、もう一つ具体的に。
VBじゃないけど。
// 30fpsを目標とする場合
#define FPS 30
#define ONE_FRAME_TIME (1000/FPS)
// 次の描画の目標時間
int next_draw_time = GetTickCount() + ONE_FRAME_TIME;
// game loop
while (1) {
//ゲームの計算だけする
process_a_game_frame();
// まだ時間があるなら、目標時間まで待って描画を行う
// そうでないなら描画をスキップ
int now_time = GetTickCount();
if (next_draw_time > now_time) {
Sleep(next_draw_time - now_time);
// 描画
draw_all_game();
flip_screen();
}
// 次の描画の目標時間
next_draw_time += ONE_FRAME_TIME;
}
GetTickCount()がミリ秒単位でシステム時間を取ってくる関数、
Sleep()は、ミリ秒を指定して実行をとめる関数。
実はこれだと、計算に時間がかかる場合、ずっと描画されなくなってしまう
という罠がある。
その辺が心配ならもう少し工夫する必要あり。