2013-12-25 4 views
2

Вчера я написал тему, в которой обсуждался мой цикл игры (в java) и как он работает.Рассчитать FPS в Java Game

Мой игровой цикл работает полностью, и я знаю почему, но теперь я просто не знаю, как рассчитать FPS (Frames Per Second) и распечатать его каждую секунду.

Вчера я получил ответ об этом, но он объяснил это словами, и я не мог этого понять.

Если бы кто-нибудь мог мне помочь (с примером кода?: D), это было бы здорово.

Вот моя игра петля:

 while (running) { 

     start = System.nanoTime(); 

     update(); 
     draw(); 
     drawToScreen(); 

     elapsed = System.nanoTime() - start; 

     wait = targetTime - elapsed/1000000; 
     if (wait < 0) { 
      wait = 5; 
     } 

     try { 
      Thread.sleep(wait); 
     } catch (Exception e) { 
      Game.logger.log("ERROR! Printing Stacktrace..."); 

      e.printStackTrace(); 
     } 

    } 

ТАКЖЕ:

В моей JFrame, когда-либо я называю SetName (строка) он никогда не работает/обновления на раме - Свяжите меня к теме?

+1

Ваш «ТАКЖЕ» кажется другим вопросом, и почти невозможно ответить без контекста. – Trojan

+0

Что касается, я думаю, что вы задаете имя Thread. – Obicere

+0

Вы также можете проверить мой ответ [здесь] (http://stackoverflow.com/a/20887703/1021943) - может оказаться полезным. –

ответ

2

Для этого можно использовать простой счетчик и Timer.scheduleAtFixedRate.

Отказ от ответственности: я не знаю, является ли это лучшим методом; это просто.

int totalFrameCount = 0; 
TimerTask updateFPS = new TimerTask() { 
    public void run() { 
     // display current totalFrameCount - previous, 
     // OR 
     // display current totalFrameCount, then set 
     totalFrameCount = 0; 
    } 
} 

Timer t = new Timer(); 
t.scheduleAtFixedRate(updateFPS, 1000, 1000); 

while (running) { 
    // your code 
    totalFrameCount++; 
} 
+0

Что касается доступа к переменным: внутри 'run()', вы можете получить ошибку для изменения 'totalFrameCount'. Если это так, поместите это назначение в другую функцию (возможно, 'resetFrameCount()") и вызовите эту функцию вместо прямого назначения. Кажется, я помню эту ошибку. – Trojan

+0

Мне всегда казалось, что статичность 'static' перед глобальной переменной сделает ее потокобезопасной. – SSpoke

+0

@SSpoke У вас есть источник для этого? – Trojan

2

Самый простой способ сделать это, чтобы сохранить переменную whatTheLastTimeWas хранить и делать это, где вы хотите, чтобы проверить частоту кадров:

double fps = 1000000.0/(lastTime - (lastTime = System.nanoTime())); //This way, lastTime is assigned and used at the same time. 

В качестве альтернативы, вы можете сделать счетчик FPS следующим образом:

class FPSCounter extends Thread{ 
    private long lastTime; 
    private double fps; //could be int or long for integer values 

    public void run(){ 
     while (true){//lazy me, add a condition for an finishable thread 
      lastTime = System.nanoTime(); 
      try{ 
       Thread.sleep(1000); // longer than one frame 
      } 
      catch (InterruptedException e){ 

      } 
      fps = 1000000000.0/(System.nanoTime() - lastTime); //one second(nano) divided by amount of time it takes for one frame to finish 
      lastTime = System.nanoTime(); 
     } 
    } 
    public double fps(){ 
     return fps; 
    } 
} 

Тогда в вашей игре, есть экземпляр FPSCounter и вызвать nameOfInstance.interrupt();, когда один кадр закончена.

+0

этот код сделает его 1 fps постоянно .. нужно избавиться от этого 'Thread.sleep (1000);' lol. – SSpoke

+0

@SSpoke На самом деле это не так. 'Thread.sleep (1000);' - ждать прерывания. В игровом классе вам нужен экземпляр 'FPSCounter', и вы вызываете' nameOfInstance.interrupt(); 'когда каждый кадр завершен. Вы должны прочитать [this] (http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html). – Justin

+0

Но похоже, что бесконечный цикл будет спать каждую секунду независимо от того, вы вызываете 'nameOfInstance.interrupt();' или нет. Я бы подумал, что это будет что-то вроде этого: public void run() {while (true) {if (isInterrupted()) {try {Thread.Sleep (1000); } catch() {}}}} 'чтение этой статьи, кажется, вы хотите, чтобы этот поток управлял gameLoop, когда этот поток fps приостанавливается, вы хотите, чтобы игровой цикл также приостанавливался? – SSpoke

Смежные вопросы