FPSを一定に保つクラスを作成してみました。

Androidでゲームを制作する為に、FPSを一定に保つクラスを作成しました。
(フレームスキップの機能はありません)

スレッドの中で処理を無限ループさせている形を想定しています。

package 好きなパッケージ名で組み込んでください;

import java.util.concurrent.TimeUnit; 
import android.util.Log; 

/** 
* FPSの表示・調整するクラス 
*/ 
public class FPSManager { 
  // 1秒(ナノ秒単位) 
  private static long ONE_SEC_TO_NANO = TimeUnit.SECONDS.toNanos(1L); 

  // 1ミリ秒(ナノ秒単位) 
  private static long ONE_MILLI_TO_NANO = TimeUnit.MILLISECONDS.toNanos(1L); 

  private int maxFps; 
  private int[] fpsBuffer; 
  private int fpsCnt; 
  private long startTime; 
  private long elapsedTime; 
  private long sleepTime; 
  private long oneCycle; 

  /** 
   * コンストラクタ 
   * @param fps 動作FPS 
   */ 
  public FPSManager(int fps) { 
    maxFps = fps; 
    fpsBuffer = new int[maxFps]; 
    fpsCnt = 0; 
    startTime = System.nanoTime(); 
    oneCycle = (long)(Math.floor((double)ONE_SEC_TO_NANO / maxFps)); 
  } 

  /** 
   * 状態更新 
   * @return sleepする時間(ナノ秒) 
   */ 
  public long state() { 
    fpsCnt++; 
    if (maxFps <= fpsCnt) { 
      fpsCnt = 0; 
    } 

    elapsedTime = System.nanoTime() - startTime; 
    sleepTime = oneCycle - elapsedTime; 

    // 余裕が無い場合でも1ミリ秒はsleepさせる 
    if (sleepTime < ONE_MILLI_TO_NANO) { 
      sleepTime = ONE_MILLI_TO_NANO; 
    } 

    int fps = (int)(ONE_SEC_TO_NANO / (elapsedTime + sleepTime)); 
    fpsBuffer[fpsCnt] = fps; 

    startTime = System.nanoTime() + sleepTime; 

    return sleepTime; 
  } 

  /** 
   * FPSの取得 
   * @return 現在のFPS 
   */ 
  public int getFps() { 
    int allFps = 0; 
    for (int i = 0; i < maxFps; i++) { 
      allFps += fpsBuffer[i]; 
    } 

    return allFps / maxFps; 
  } 
}

使い方。
まずは初期化。

// FPS:30で動作させる
FPSManager fpsM = new FPSManager(30);

一定間隔で実行したいThreadのRun()メソッド内で

TimeUnit.NANOSECONDS.sleep(fpsM.state());

を呼ぶ。
以上。

2 Responses

  • […] 現在開発中のシューティングゲームでは、スレッドの速度制御がかなり大切になります。 どの機種で動作させても速度は一定である必要があります。その為のクラスを作ろうとしたのですが、ネットを探すと見つかったので、 こちらのFPSを一定に保つクラスを使っています。 […]

  • Pretty great post. I just stumbled upon your blog and wanted to mention that I have really loved browsing your weblog posts. After all I will be susibrcbing on your feed and I’m hoping you write once more very soon!

Leave a Reply