【发布时间】:2011-05-08 20:14:06
【问题描述】:
我正在尝试制作一个显示 FPS 的字符串,但是,我如何才能真正获得我的程序 FPS?我想这样做
g.drawString(getFPS(), 10, 10)
如何获得我的 FPS?
【问题讨论】:
-
请提供更多细节。
-
我只想让一个字符串显示我的 FPS。
标签: java frame-rate
我正在尝试制作一个显示 FPS 的字符串,但是,我如何才能真正获得我的程序 FPS?我想这样做
g.drawString(getFPS(), 10, 10)
如何获得我的 FPS?
【问题讨论】:
标签: java frame-rate
这段代码为我做的。把它放在你的主程序循环中:
//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要绘制的数据
【讨论】:
计算经过的时间,1000/elapsedTime 将是您的 fps。
【讨论】:
虽然这个问题听起来有点模糊,但我还是会尽力回答。由于原始帖子可以追溯到 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();
}
}
}
}
我的方法(相对于以前的解决方案)的明显优势是:
Graphics 或 JLabel 之类的东西,就可以了。javax.Swing.Timers 或线程一起使用 - 在您尝试评估其性能的定时器/线程上调用 submitReading(),同时从另一个定时器/线程运行 getFrameRate() 以获得结果(例如 - 您可以将其写入JLabel、文件等)。(PS.: 请注意,对于 Swing,所有绘制操作都需要在事件调度线程 (EDT) 上完成。因此,如果不使用特殊命令,则不应将绘制工作委托给其他(原始)线程,例如SwingUtilities.invokeLater(..))。
希望这会有所帮助!
【讨论】: