在遵循 Java 游戏开发教程(指南由 Kaarin Gaming 编写,来源:https://www.youtube.com/watch?v=aFS9Whsoecc&list=PL4rzdwizLaxYmltJQRjq18a9gsSyEQQ-0&index=8)时,我遇到了错误限制我的 FPS 计数。除了几行之外,他的代码看起来与我的代码大部分相似,
public void paintComponent(Graphics g) {
super.paintComponent(g);
updateRectangle();
g.setColor(color);
g.fillRect((int)xDelta, (int)yDelta, 50, 50);
// basic FPS counter
frames++;
if(System.currentTimeMillis() - lastCheck >= 1000) {
lastCheck = System.currentTimeMillis();
System.out.println("FPS: " + frames);
frames = 0;
}
repaint();
}
而repaint();在那里,游戏以 2300 FPS 运行,这太高了。所以他修复它的方法是添加一些代码(我已经添加了),然后删除 repaint(); 。然而,当我这样做时,游戏将无法运行,FPS 将保持在静态 1。
我尝试改变刷新帧之间的间隔,移动 repaint();周围的代码的不同部分可能需要它/还没有它,我再次观看了视频以发现错误,但我还没有发现任何东西。
还有一点需要注意,我是编程新手。所以如果你有答案,请解释一下原因,以便我更好地理解,谢谢。
我不认为在制作游戏的同时学习编码本质上是坏事。您会遇到需要思考和良好解决问题的现实问题。我假设您的更新例程每秒也被调用 2300 次。如果它记录最后一次执行的时间,那么如果该时间小于(1000 毫秒除以所需帧速率),您应该从该函数返回。
您拥有的是一个递增
frames
计数器的函数。当 System.currentTimeMillis() - lastCheck >= 1000
更新 lastCheck
时间并重置 frames
的计数器时。
这里似乎错误的是
repaint()
所在的位置。每次调用 paintComponent
时都会调用它,而不是每次您希望允许实际的 repaint()
时调用。
将重绘放入 if 语句中也不起作用。这只是在输出 FPS 速率之前等待 1000 毫秒(1 秒)。
你也缺乏我在开场白中描述的功能。
您需要:
我还没有将正在运行的示例放在一起,但我认为以下是您所需要的,尽管它可能需要调整,因为我还没有测试过它。
// class member fields
long lastRepaintTime = System.currentTimeMillis();
long desiredMaxFrameRate = 30;
long frameRateInterval = 1000 / desiredMaxFrameRate;
public void paintComponent(Graphics g) {
super.paintComponent(g);
long now = System.currentTimeMillis();
// only do UI activity if the frameRateInterval has elapsed
if (now - lastRepaintTime >= frameRateInterval)
{
frames++; // only count frames we actually render
updateRectangle();
g.setColor(color);
g.fillRect((int)xDelta, (int)yDelta, 50, 50);
// basic FPS counter - check if it's been 1000+ms since we last output the frame count
if(now - lastCheck >= 1000) {
lastCheck = System.currentTimeMillis();
System.out.println("FPS: " + frames);
frames = 0;
}
repaint(); // perform the actual repaint/rendering
lastRepaintTime = System.currentTimeMillis(); // update the lastRepaintTime
}
}