制作FPS淋浴?

时间:2011-05-08 20:14:06

标签: java frame-rate

我正在尝试用FPS显示一个字符串,但是,我如何实际获得我的程序FPS?我想用

g.drawString(getFPS(), 10, 10)

如何获取我的FPS?

3 个答案:

答案 0 :(得分:9)

这段代码适合我。把它放在主程序循环中:

//To Measure FPS
private long now;
private int framesCount = 0;
private int framesCountAvg=0; 
private long framesTimer=0;

//Main Game Loop
    while (isRunning)
    {
        //Record the time before update and draw
        long beforeTime = System.nanoTime();
        //... Update program & draw program...
        // DRAW FPS: 
        now=System.currentTimeMillis(); 
        gEngine.drawFPS(c, framesCountAvg);
        framesCount++; 
        if(now-framesTimer>1000)
        { 
              framesTimer=now; 
              framesCountAvg=framesCount; 
              framesCount=0; 
        }}

调用“gEngine.drawFPS”只是告诉我的主要绘制方法将fps包含在屏幕顶部(而c是我的Canvas) - 你可以使用类似的方法为你的“g”类提供正确的framesCountAvg要绘制的数据

答案 1 :(得分:2)

计算经过的时间,1000/elapsedTime将是你的fps。

答案 2 :(得分:0)

虽然这个问题听起来有点模糊,但我仍然会尽我所能并回答它。由于原始帖子可以追溯到2011年,因此OP很可能不会从我的答案中获益。希望它能为那些关注的人提供更好的基础(前两个答案看起来有点过于混乱和简洁)。

这是我经常用于收集和显示各种Java GUI应用程序的帧速率的代码片段:

public class FrameRateCounter {

    private Map<Long, Long> measurementTimes;


    public FrameRateCounter() {
        measurementTimes = new HashMap<Long, Long>();
    }

    public synchronized void submitReading() {
        long measurementTime = System.nanoTime();
        long invalidationTime = System.nanoTime() + 1000000000;
        measurementTimes.put(measurementTime, invalidationTime);
    }

    public int getFrameRate() {
        performInvalidations();
        return measurementTimes.size();
    }

    private synchronized void performInvalidations() {
        long currentTime = System.nanoTime();
        Iterator<Long> i = measurementTimes.keySet().iterator();
        while(i.hasNext()) {
            long measurementTime = i.next();
            long invalidationTime = measurementTimes.get(measurementTime);
            if(invalidationTime < currentTime) {
                i.remove();
            }
        }
    }
}

我的方法(关于以前的解决方案)的明显优势是:

  1. 关注点分离 - 您不希望FPS计数计算等微不足道的事情污染程序的“主循环”。因此,将此逻辑隔离到单独的组件/类中。
  2. GUI组件框架的独立性 - 最好尽可能避开与框架相关的解决方案。在目前的情况下,这很容易 - 只是避免在计算中引用GraphicsJLabel之类的内容而且你很好。
  3. 存储在散列图中的所有测量 - 哈希映射以其快速查找时间(时间复杂度几乎为O(1))而闻名。因此,进行必要的比较不应对您的应用程序的整体性能产生任何明显影响。
  4. 可以与多个javax.Swing.Timer或线程一起使用 - 在您从另一个计时器/线程运行submitReading()时尝试评估其性能的计时器/线程上调用getFrameRate()以获取结果(例如 - 您可以将其写入JLabel,文件等)。
  5. (PS。:请注意,使用Swing,所有绘制操作都需要在事件调度程序线程(EDT)上完成。因此,不应使用特殊命令(例如特殊命令)将绘图工作委托给其他(原始)线程。 SwingUtilities.invokeLater(..))。

    希望这有帮助!