2012-05-10 5 views
2

HTC Wildfire Sで一定の平均60 FPSで画面をレンダリングするゲームの飛行機の狂気を見ました。私は同じスマートフォンで結果を真似しようとしていましたが、なぜ私のプログラムのみを理解できません平均15FPSを上回っていますか?Android Game Loop:平均で60FPSに達するには?

飛行機の狂気のフレームレートはどのように表示されますか?設定にFPSカウンターを切り替えるオプションがあります。私は鉱山をENABLEDに設定しました。

ここに私のコードです。これは私のゲームのループです。このことから、いくつかの興味深い結果があります。

public void run() { 
     // Average FPS for Android is 15 on Test Phone is 13 through 15. 
     // Max FPS is 20. 
     // Occasional bursts of FPS60 may occur. 
     long now, lastTime = System.nanoTime(); 
     double process = 0.0; 
     final double NSperTick = 1000000000.0/60.0; 
     while (running) { 
      now = System.nanoTime(); 
      process += (now - lastTime)/NSperTick; 
      lastTime = now; 
      boolean ticked = false; 
      while (process >= 1) { 
       process -= 1; 
       tick(); 
       ticked = true; 
      } 
      if (ticked) { 
       render(); 
      } 
      swap(); 
      try { 
       Thread.sleep(2); 
      } 
      catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

誰もが、私は60 FPSの平均値を得ることができるように、など、改善する必要があるもの、私が間違ってやっているものを私に伝えることができますか?このゲームのループは、Java(Androidではなく)で動作しているときには実用上問題ないので、スマートフォンのフレームレートにどのようなロジック部品が影響しているのかよくわかりません。

ありがとうございます。


EDIT:すべての機能をManに知らせる必要があるように見えます。

private void render() { 
    synchronized (holder) { 
     if (holder.getSurface().isValid()) { 
      Canvas c = holder.lockCanvas(); 
      c.drawRGB(0x44, 0x55, 0xff); 
      ball.render(c); 
      holder.unlockCanvasAndPost(c); 
     } 
    } 
} 

private void swap() { 
} 

private void tick() { 
    float[] values = {meter.X, meter.Y, meter.Z}; 
    ball.tick(values); 
    handler.tick(ball); 
} 

そして、ここで私は私のゲームの平均FPSをご確認方法は次のとおりです。

03-12 14:29:21.008: D/FrameRate(3533): 14 
03-12 14:29:22.061: D/FrameRate(3533): 15 
03-12 14:29:23.048: D/FrameRate(3533): 14 
03-12 14:29:24.033: D/FrameRate(3533): 14 
03-12 14:29:25.018: D/FrameRate(3533): 14 
03-12 14:29:26.000: D/FrameRate(3533): 14 
03-12 14:29:27.056: D/FrameRate(3533): 15 
03-12 14:29:28.047: D/FrameRate(3533): 14 
03-12 14:29:29.026: D/FrameRate(3533): 14 
03-12 14:29:29.995: D/FrameRate(3533): 14 
03-12 14:29:31.037: D/FrameRate(3533): 15 
03-12 14:29:32.015: D/FrameRate(3533): 14 

EDIT 2:より多くの情報があります:

public void run() { 
    // Average FPS for Android is 15 on Test Phone is 13 through 15. 
    // Max FPS is 20. 
    // Occasional bursts of FPS60 may occur. 
    long now, lastTime = System.nanoTime(); 
    int frames = 0; 
    double process = 0.0; 
    long frameTime = System.currentTimeMillis(); 
    final double NSperTick = 1000000000.0/60.0; 
    while (running) { 
     now = System.nanoTime(); 
     process += (now - lastTime)/NSperTick; 
     lastTime = now; 
     boolean ticked = false; 
     while (process >= 1) { 
      process -= 1; 
      tick(); 
      ticked = true; 
     } 
     if (ticked) { 
      //render(); 
      frames++; 
     } 
     swap(); 
     try { 
      Thread.sleep(2); 
     } 
     catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     if (frameTime <= System.currentTimeMillis() - 1000) 
     { 
      Log.d("FrameRate", Integer.toString(frames)); 
      frameTime += 1000; 
      frames = 0; 
     } 
    } 
} 

そしてここでは、DDMSからの結果は、私はrender()関数でこのコードをコメントアウトしました:

synchronized (holder) 

しかし、私は14~15FPSしか達成できません。これは私が突破することができない限界ですか?

+0

'render()'を呼び出さないとどうなりますか?それはあなたが無視しているような明白なことです。レンダリングにはあなたの時間よりも時間がかかるかもしれません。 – unwind

+0

tick()、render()、swap()のメソッドを見ずに私を助けることはできません –

+0

@unwind tick()、render()、swap()の情報を追加しました。レンダリング()でオブジェクトボールを呼び出したことに気付きました。私はその上の機能を拡張するべきですか? –

答えて

2

あなたのレンダリングループでの同期の理由を理解できません。何らかの理由ですぐにロックを取得できない場合、アプリケーションがフリーズしているように見せかけて、レンダリングスレッドをロックする可能性があるため、これは悪いフォームです。また、ロックを取得するには時間がかかります。

レンダリングスレッドをロックする必要があるようにデータを整理している場合は、デザインをリファクタリングする必要があります。

UIスレッドで同期しないでください!

+0

新しいスレッドを作成し、そのスレッドを使用してホルダーを同期したり、UIスレッドを同期させたりしますか? –

+0

こんにちは、もう少し詳しい情報を追加しました。 synchronized(holder)を削除しても、問題はまったく解決されません。 :/ –

+0

これは一般に投票されました。 –

0

イメージ/テクスチャまたはsthのレンダリングを減らしましたか?たぶんあなたの携帯電話はちょっと弱すぎるかもしれません。そうでなければ、数ミリ秒で少し眠ろうとするかもしれません。

+0

私は現在、SurfaceViewのCanvasに1ビットマップと1青の背景を描画しています。私はOpenGL ESを使用する可能性のあるものは実行していません。また、私の携帯電話は、飛行機の狂気を実行することができます。私はそれがOpenGLで平均60FPSであると信じていました。つまり、私の電話はそれほど弱いわけではありません。私はThread.sleep()関数で少し演奏しましたが、大したことはありません。 :/ –

0

libgdxなどのゲームフレームワークを使用することを強くお勧めします。あなたのアプリケーションに役立つたくさんのサンプルとチュートリアルがあります。あなたはそれをデスクトップやHTML5に簡単に移植することは言及していません。

+0

私はその申し出を断らなければなりません。私はゲームのフレームワークを是非使ってはいけません。 :/ –