如何解决如何在简单的java游戏循环中提高帧率?
我正在开发一个 Java 2d 游戏,使用这个简单的游戏循环将 FPS 和 UpdatesPS 限制为 60:
public void run() {
final int MAX_FPS = 60;
final int MAX_UPS = 60;
final double fOPTIMAL_TIME = 1000000000 / MAX_FPS;
final double uOPTIMAL_TIME = 1000000000 / MAX_UPS;
double uDeltaTime = 0,fDeltaTime = 0;
int frames = 0,updates = 0;
long startTime = System.nanoTime();
long timer = System.currentTimeMillis();
// GameLOOP starts here
while (running) {
long currentTime = System.nanoTime();
uDeltaTime += (currentTime - startTime);
fDeltaTime += (currentTime - startTime);
startTime = currentTime;
if (uDeltaTime >= uOPTIMAL_TIME) {
gameUpdate();
updates++;
uDeltaTime -= uOPTIMAL_TIME;
}
if (fDeltaTime >= fOPTIMAL_TIME) {
gameRender();
gameDraw();
frames++;
fDeltaTime -= fOPTIMAL_TIME;
}
if (System.currentTimeMillis() - timer >= 1000) {
fps = frames; //saves the current FPS
ups = updates; //saves the current UPS
updates = 0;
frames = 0;
timer += 1000;
}
}
}
循环有效,但在开始游戏后的前大约 10 秒内我只能获得 30 FPS。
等待后,FPS 上升到想要的 60。我没有问题等待几秒钟让程序稳定并达到想要的帧率。但是我找不到像方法一样的原因,因为它在启动后正在获取一个大文件而丢弃FPS。
你知道为什么我的引擎需要这么长时间来稳定帧率吗?
感谢您的帮助!
解决方法
我认为这应该可以解决问题:
public static void run()
{
final int desiredFPS = 60;
final int desiredUPS = 60;
final long updateThreshold = 1000000000 / desiredUPS;
final long drawThreshold = 1000000000 / desiredFPS;
long lastFPS = 0,lastUPS = 0,lastFPSUPSOutput = 0;
int fps = 0,ups = 0;
loop:
while(true)
{
if((System.nanoTime() - lastFPSUPSOutput) > 1000000000)
{
System.out.println("FPS: " + (double)fps);
System.out.println("UPS: " + (double)ups);
fps = 0;
ups = 0;
lastFPSUPSOutput = System.nanoTime();
}
if((System.nanoTime() - lastUPS) > updateThreshold)
{
lastUPS = System.nanoTime();
updateGame();
ups++;
}
if((System.nanoTime() - lastFPS) > drawThreshold)
{
lastFPS = System.nanoTime();
drawGame();
fps++;
}
// Calculate next frame,or skip if we are running behind
if(!((System.nanoTime() - lastUPS) > updateThreshold || (System.nanoTime() - lastFPS) > drawThreshold))
{
long nextScheduledUP = lastUPS + updateThreshold;
long nextScheduledDraw = lastFPS + drawThreshold;
long minScheduled = Math.min(nextScheduledUP,nextScheduledDraw);
long nanosToWait = minScheduled - System.nanoTime();
// Just in case
if(nanosToWait <= 0)
continue loop;
try
{
Thread.sleep(nanosToWait / 1000000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
编辑:我现在解决了这个问题!问题是我在场景更新/绘制后保存了 lastFPS/lastUPS,当我在场景绘制/更新之前设置 lastUPS/lastFPS 时,我们得到了所需的 fps!
这段代码的另一个优点是它不消耗整个cpu核心(我测量了差异,你的代码消耗了100%,而我的代码只消耗了大约10%。如果你想自己测量,请注意,出于某种原因,执行代码的核心会定期切换(至少我测量代码时是这种情况))
顺便说一句,如果您使用 LWJGL(或有直接访问像 GLFW 这样的窗口库)您可以激活 V-Sync,这会将您的 fps 降低到 60 fps。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。