制作一款FPS淋浴游戏?

3

我想制作一个显示FPS的字符串,但是,我该如何获取程序的FPS? 我想用以下方法实现

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

如何获取我的FPS?


9
请提供更多细节。 - SLaks
我只想让一个字符串显示我的FPS。 - Stan
3个回答

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数据来绘制


2

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


0

虽然这个问题听起来有点模糊,但我会尽力回答。因为原帖是2011年发布的,所以发帖人可能无法从我的回答中受益。但希望对后来者有所帮助(前两个答案似乎有些混乱和简短)。

这里是一个代码片段,我经常用于收集和显示各种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或线程一起使用 - 在运行getFrameRate()以获取结果时,在您尝试评估其性能的计时器/线程上调用submitReading()(例如-您可以将其写入JLabel、文件等)。
(注:请注意,使用Swing时,所有绘图操作都需要在事件分派线程(EDT)上完成。因此,在没有使用特殊命令(如SwingUtilities.invokeLater(..))的情况下,不应将任何绘图工作委托给其他(原始)线程。)
希望这可以帮到你!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接