フレーム待ちを行っている部分の処理を時間軸で図に書いてみたらすぐに原因が分かった。
今まで間違っていたフレーム待ちの処理内容はあるサンプルソースを参考にしており、そのときの記事はこれ→[id:toburau:20080710]
void WaitFrame(unsigned int framepersec) { static Uint32 next_tick = 0; Uint32 this_tick; this_tick = SDL_GetTicks(); if ( this_tick < next_tick ) { SDL_Delay(next_tick-this_tick); } next_tick = this_tick + (1000/framepersec); }
この処理では次のフレーム待ちのカウントの計算が間違っている。次のフレーム待ちの値をSDL_Delay()で待つ前の値から計算してしまっている。正しくはこちら。
void WaitFrame(unsigned int framepersec) { static Uint32 next_tick = 0; Uint32 this_tick; this_tick = SDL_GetTicks(); if ( this_tick < next_tick ) { SDL_Delay(next_tick-this_tick); } next_tick = SDL_GetTicks() + (1000/framepersec); }
これで自分が期待した通りのタイミングでゲームのループがまわるようになった。