Fujisaki考えてみれば当たり前な方法ですが、ぐぐっても見つからなかったので...。世の中に存在する大体のライブラリでは、時間をミリ秒単位で計測することができます。一秒間は1000ミリ秒です。世の中、特にこの日本に存在するゲームは、大体60FPSで動いています。一秒間に60回画面上の絵が更新されるということです。1/60秒は、16.666666666666667秒。1ミリ秒が精度のタイマーでは、正確に測定することはできません。ゲームスピードを60FPSにしたいなら、なんとか測定しなければなりません。そこで、多くのゲームではいろいろな方法でこの問題を解決してきました。■方法1:1/60秒≒16ミリ秒と近似する。諦めてるのがこの方法です。この方法だと、1000ミリ秒/16ミリ秒=62.5となるので、60FPSより少し早くなってしまいますが、目をつぶります。//描画しても時間が余ってたら・・・sleep(nextFrame-now);//ミリ秒精度で処理を中断する関数}}nextFrame+=16;}}■方法2:浮動小数点を使うsleepも、現在の時間を取得する関数もミリ秒の精度しかありませんが、それらを管理する変数だけは浮動小数点を使う方法です。この方法を使うと、実際には16ミリ秒のフレームと17ミリ秒のフレームが、1:2の割合で現れます。ソースコードを見ていただけたほうが早いでしょう。//描画しても時間が余ってたら・・・//型変換が必要。sleep(static_cast<uint32_t>(nextFrame-now));}}nextFrame+=frameInterval;}}この方法ではかなり正確に60FPSを達成できますが、「計算の遅いfloat+型変換まで必要、よって遅そう」、「浮動小数点の精度は直感的に分かりづらい」(からなんか気持ち悪い)という精神衛生上の問題が発生します。実際には一秒間に60回しか行わないので、パフォーマンス上の問題は無いでしょうし、そもそもミリ秒精度しか測れない以上キッチリ60FPSを測ることも不可能なので、floatの誤差を気にする必要は無いと思いますけど。なんか気持ち悪いんです...(ぇ■方法3:vsyncに任せるDirectXやらOpenGLやらのゲームライブラリは、システムがモニタに画面を描画するタイミングまで待ってくれたりします。これを垂直同期(vsync)を取るといい、この方法を使うとシステムが画面をディスプレイに描画している最中にゲーム画面を更新する事がなくなるので、画面がガクついたりしなくなります。この方法は自分で時間を測る必要もないし†1、画面も綺麗になるしでいいこと尽くめなのですが、ひとつだけ問題があります。「すべてのモニタが60FPSとは限らない」、という点です。75FPSの画面もあれば、50FPSの画面もあります。垂直同期を取るとこういった場合にゲームが早くなったり遅くなったりしてしまいます。vsyncがサポートされているとは限りません。グラフィックカードの設定でvsyncを無効にすることもできます(OpenGLの場合。DirectXは存じません)。■今回の方法:浮動小数点でなく分数で計算する長々と書いてきましたが、やっと今回の本題に入れます。vsyncが一番良いのはそのとおりなのですが、諸々の事情で使えないこともあるとわかりました。いうことはやっぱりタイマを用いて制御しなければならないこともあるわけです。方法2のfloatを用いる方法を継承しつつ、精神衛生上よろしくないfloatを取り除きます。一秒間に1000回回るカウンタを使って一秒間に60回を測る方法...。最小公倍数の6000を基準にして、分数で測ってしまいましょう†2。//描画しても時間が余ってたら・・・sleep((nextFrame-now)/6);}}nextFrame+=100;}}問題はタイマーの限界が6倍早く来てしまう点でしょうか...。SDLのSDL_GetTicksなどの32ビット整数を返すタイマでは49日間で0に戻ってしまいますが、6倍するのでだいたい8日でオーバーフローしてしまいます。抽象化すると「”一定期間内にn回まわるカウンタ”で”一定期間内にm回まわるカウンタ”をつくる方法」ですので、フレームレート以外でも活用していただけます。そもそも今回の内容は、現在開発中のファミコンエミュレータで、サウンドとCPUを同期する方法を考えていて思いつきました。いえその内容をそのまま書いても汎用性が低いので、フレームレートに置き換えて記述しています。書いていて中学受験を思い出しました...。進化するシューティングゲーム”GENETOS”が最近一番の個人的ヒット作です!ゲームシステムがゲーム進行にあわせ進化してくという発想の斬新さ、STGの歴史をうまくまとめ上げた構成力、ドラマチックな演出、遊びやすい難易度...。BGMです!特に最終面のBGMはステージ演出と相まって最高です!今回、そのGENETOSのBGMや画像ファイルに掛けられてる暗号を解除するツールを作成しました。このツールを利用することで、BGMを暗号化することもできます。BGMの差し替えも可能です!(※制限あり、後述)■ダウンロードver.1.00(2010/11/06)ライセンスはGPL3です。(アーカイブ内のLICENSE.TXTを参照)■使い方GENETOSの、bgmフォルダ内の”○○○.mp3.ore”ファイル、または”○○○.mid.ore”を”oreshiki.exe”にドラッグアンドドロップすると同じフォルダに復号化されたファイルがでてきます。同様に、img内の.oreファイルも復号化できます。soundフォルダ内に入っている効果音ファイルは実は暗号化されてないので、.wav.oreを.wavに変更するだけで再生することができます。■解説ファイルの先頭128バイトを、”oreshikioreshikioreshiki.....”という”oreshiki”がぐるぐると連続する文字列とxorを取っただけです。ファイルの大部分は平文ですwこれを、再生直前に復号化して、再生が終わったら再び暗号化して再生できないようにする、という方法で暗号化しています。ライブラリがメモリ上に展開されたmp3ファイルの再生に対応していなくて、その仕様と妥協しあった結果、でしょうか?■BGM差し替え.mp3ファイルや.midファイルをこのソフトにドラッグアンドドロップすることで暗号化することもできます!このソフトで暗号化したファイルを、元のBGMのファイルと入れ替えることでBGMの差し替えを行うことができます。ファイルフォーマットのチェックがシビアなのか、にこさうんど#等、ネット上から拾ってきたmp3はそのままでは再生に失敗することも多いので、一度wavに戻してからlame等で再エンコードして使うのを推奨します。この方法ではステージがmidiのステージはmidiのファイルで、mp3のステージはmp3ででしか差し替えることができません。プログラムを書き換えれば可能で、一応そのための改造パッチも作ってあります。テストした上で公開できそうなら公開する予定ですが、いつになるやら。