Python中文网

一个关于 编程问题的解答网站.

有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

爪哇做FPS淋浴?

我想用FPS来制作一个字符串,但是,我怎么才能真正获得我的节目FPS呢?我想和你一起做

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

我如何获得FPS


共 (3) 个答案

  1. # 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. # 2 楼答案

    计算经过的时间,1000/elapsedTime将成为您的fps

  3. # 3 楼答案

    虽然这个问题听起来有点模糊,但我还是会尽我所能回答它。因为最初的帖子可以追溯到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. 存储在hashmap中的所有测量值——hashmap以其快速的查找时间(时间复杂度接近O(1))而闻名。因此,进行必要的比较不应该对应用程序的整体性能产生任何明显的影响
    4. 可以与多个javax.Swing.Timer或线程一起使用-在试图评估其性能的计时器/线程上调用submitReading(),同时从另一个计时器/线程运行getFrameRate()以获得结果(例如,可以将其写入JLabel、文件等)

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

    希望这有帮助