2016-05-26 2 views
0

私はJavaでボンバーマンのゲームを作っていますが、ゲームはプロセッサとCPUのオーバーロードにPCが遅くなっているようです。私は別のゲームでこのループを使用しましたが、パフォーマンス上の問題を引き起こすことなく正常に動作しました。しかし、私は単純にgameloopをコメントアウトすることにより、()私が使用している主要なパフォーマンスの問題ゲームのループパフォーマンスの問題

ゲームループの原因となることがわかりました:問題を引き起こしている可能性があり、このループに問題がある

public void start() { 
    window.setVisible(true); 
    running = true; 
    int fps = 60; 
    double timePerTick = 1e9/fps; 
    double delta = 0; 
    long now; 
    long lastTime = System.nanoTime(); 

    while (running) { 
     now = System.nanoTime(); 
     delta += (now - lastTime)/timePerTick; 
     lastTime = now; 
     if (delta >= 1) { 
      gameLoop(); /* commenting this out will cause major performance 
         * problem to the PC */ 
      delta--; 
     } 
    } 
} 

@Override 
public void gameLoop() { 
    if(!gameover){ 
     run(); 
     gui.repaint(); 
    } 
} 

、またはパフォーマンスの問題を軽減するより良い方法があります

[編集] 私はタイマーと同様のタスクを行うためにループを変更しました、それは正常に動作し、何かこの問題ではまだ間違っている長期的な問題)??あなたは、あなたのニーズに応じてお使いの場合には、お使いのCPUの100%を消費し任意の一時停止せずに無限ループを作っている

public void start(int fps){ 
    window.setVisible(true); 
    running = true; 
    gameTimer.scheduleAtFixedRate(new GameTimer(), 0, 1000/fps); 
} 

private class GameTimer extends TimerTask{ 

    @Override 
    public void run(){ 
     gameLoop(); 
    } 
} 
+0

私はこの記事を読むでしょう。 http://www.java-gaming.org/index.php?topic=24220.0 – Orin

+0

もっと効率的なものを書くためにゲームループについてもっと読むことをお勧めします。 – eldo

答えて

1

、あなたのフレームレートを定義し、次のように応じてスリープ時間の長さを設定する必要があります。

run(); 
    gui.repaint(); 
    // Make the current thread sleeps 1 000 milliseconds which means 1 frame per sec 
    Thread.sleep(1000L); 
+0

fpsメソッドを削除してthread.sleep()を使用するように指示していますか?プレイヤーがほとんど移動できないように1秒間行いますが、別のコンピュータで異なる速度で実行するときにthread.sleepを避けるのが最善だと思いました –

+0

私はちょうどあなたが沢山のCPUを必要とするすべての時間をリフレッシュすることを避けたいと思う速度で眠るように頼んでいます。フレームレートを定義し、それに応じて睡眠を設定する –

0

スレッドがループしているため、1つのスレッドが永続的にビジー状態になります。これにより必然的にCPUリソースが奪われ、他には利用できなくなります。代わりに、常にnanoTime()を取り、十分な時間が経過したgameloop()を呼び出すの

、あなたは次の呼び出しはのThread.sleepを行わ及び呼ぶ)(gameloopするためにどの時点でを予測する必要があります()一時停止するにはスレッドまでが到着します。

long lastTick = System.currentTimeMillis(); 
long ticksPerFrame = 1000/fps; 
while (true) { 
    long nextTick = lastTick + ticksPerFrame; 
    long sleep = nextTick - System.currentTimeMillis(); 
    if (sleep > 0) { 
     try { 
      Thread.sleep(sleep); 
     } catch (InterruptedException e) { 
      throw new RuntimeException(e.getMessage(), e); 
     } 
    } 
    lastTick = nextTick; 
    gameloop(); 
} 

(コードテストしていない、唯一の一般的なアプローチを実証するためのもの)

:次のダニが原因であるときだけでミリ秒のタイムスタンプを計算するのに十分なその正確な多くの目的のために、その金額を現在の時刻を減算して眠ります

これは、システムタイマーの分解能プラス/マイナススリープの変動と同じくらい正確です。ほとんどのシステムでは、平均数ミリ秒の変動を意味します。特に、AWT/Swingをレンダリングに使用する場合は、多くのシナリオで許容されます。 repaint()コールをEDTが処理できるよりも速く配置すると、Swingによって再描画がスキップされる可能性があります。これは、ほとんどの場合、再描画キューが遅れたときに追いつくことができるため望ましい方法です。

関連する問題