【プログラミング】処理落ちに対応する考え方
実装されててアタリマエのことですが、されていないフリーゲームもちらほら見るので考え方とC言語でのサンプルだけちょっと紹介。
処理落ちに対応するには実に簡単で、小学校で習った「距離=速さ×時間」を使います。
この"時間"の部分ですが、ゲームであれば、1フレームごとに座標の更新(座標の再計算)が行われる処理が多いと思いますが、これは実に都合がよく、簡単に実装できます。
この場合での必要な要素は、
- 1秒間の移動量(速さ)
- 1フレームの処理時間(時間)
実際に見てもらったほうが早いと思うので
まずソースを貼ります
#include<Windows.h> void Loop(); void Update(); long long deltaTime = 0; int main() { Loop(); } void Update() { static float score = 0; static float scoreAdd = 100;//1秒で増えるスコア score += scoreAdd*(deltaTime / 1000.0f); } void Loop() { //無意味な無限ループ(サンプルなので適当) while (1) { static long long start = 0; static long long end = 0; //処理開始時間を記録 start = timeGetTime(); { //1フレーム内で行う処理 Update(); } //処理終了時間を記録 end = timeGetTime(); //終了時間 - 開始時間 = 1フレームにかかった処理時間 deltaTime = end - start; } }
Loop関数から見ていきましょう。
まず、座標の更新などの処理を始める前に、処理開始時の時間を取得します。
その後に必要な処理を全て行います。
処理が全て終わったら、処理終了時の時間を取得します。
このふたつを使ってサンプルのように計算することで、1フレームにかかった時間を取得することができます。
これで距離の計算に必要な"時間"が用意できましたね。
次にUpdate関数を見ていきましょう。
今回は座標計算ではないですが、1秒ごとにスコアが100ずつ増えていくようにしています。
このサンプルでは1フレームの時間(ミリ秒)がそのまま整数値となっているので、それを秒に直しています。
このプログラム例だと、
現在のスコア += (1秒に増える時間) × (1フレームの処理にかかった時間) です。
例えば、現在のスコアを0、1フレーム100ミリ秒かかったとすると、
0 += 100 × 0.1;
となり、スコアが10加算されます。
10FPSだとこれが1秒間に10回起きるわけですから、結果的に1秒で100加算されます。
ここで注意しておきたいのが、理由がない限り、少数が扱えるデータ型にしてください。
整数型にしてしまうと、切り捨てなどが起きてしまい計算がおかしくなります。
そんなことよりラーメンとじゃがバター食べたいですね。