【问题标题】:Making a FPS shower? [closed]制作 FPS 淋浴? [关闭]
【发布时间】:2011-05-08 20:14:06
【问题描述】:

我正在尝试制作一个显示 FPS 的字符串,但是,我如何才能真正获得我的程序 FPS?我想这样做

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

如何获得我的 FPS?

【问题讨论】:

  • 请提供更多细节。
  • 我只想让一个字符串显示我的 FPS。

标签: java frame-rate


【解决方案1】:

这段代码为我做的。把它放在你的主程序循环中:

//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 是我的画布) - 您可以使用类似的方法为您的“g”类提供正确的 framesCountAvg要绘制的数据

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      这是我经常用来收集和显示各种 Java GUI 应用程序的帧速率的代码 sn-p:

      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.Timers 或线程一起使用 - 在您尝试评估其性能的定时器/线程上调用 submitReading(),同时从另一个定时器/线程运行 getFrameRate() 以获得结果(例如 - 您可以将其写入JLabel、文件等)。

      (PS.: 请注意,对于 Swing,所有绘制操作都需要在事件调度线程 (EDT) 上完成。因此,如果不使用特殊命令,则不应将绘制工作委托给其他(原始)线程,例如SwingUtilities.invokeLater(..))。

      希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 2016-05-16
        • 1970-01-01
        • 2014-11-08
        • 2020-01-15
        • 2011-06-14
        • 2013-03-20
        • 1970-01-01
        • 2012-02-24
        • 2011-03-09
        相关资源
        最近更新 更多