为啥这个游戏循环滞后?
Posted
技术标签:
【中文标题】为啥这个游戏循环滞后?【英文标题】:Why is this gameloop lagging?为什么这个游戏循环滞后? 【发布时间】:2018-11-04 20:41:20 【问题描述】:我完全是 Java 新手,并尝试编写自己的小游戏循环
package com.luap555.main;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import javax.swing.Timer;
public class Game implements Runnable
private Window window;
public int width, height;
public String title;
private boolean running = false;
private Thread thread;
private BufferStrategy bs;
private Graphics g;
private int fps = 60;
private long lastTime;
private long now;
private long delta;
private long timer;
private long ticks;
private boolean initialized = false;
public Game(String title, int width, int height)
this.title = title;
this.width = width;
this.height = height;
private void init()
window = new Window(title, width, height);
Assets.init();
System.out.println("Initializing finished");
initialized = true;
private int x = 0;
private void tick()
x += 1;
private void render()
bs = window.getCanvas().getBufferStrategy();
if(bs == null)
window.getCanvas().createBufferStrategy(3);
return;
g = bs.getDrawGraphics();
g.clearRect(0, 0, width, height);
g.drawImage(Assets.unten, 0 + x, 0, 700, 350, null);
bs.show();
g.dispose();
private void runtick()
lastTime = System.currentTimeMillis();
tick();
now = System.currentTimeMillis();
delta += now - lastTime;
try
Thread.sleep((delta + 1000) / fps);
catch (InterruptedException e)
e.printStackTrace();
delta -= now - lastTime;
private void runrender()
render();
@Override
public void run()
init();
if(initialized)
while(running)
runtick();
runrender();
stop();
public synchronized void start()
if(running)
return;
running = true;
thread = new Thread(this);
thread.start();
public synchronized void stop()
if(!running)
return;
running = false;
try
thread.join();
catch (InterruptedException e)
e.printStackTrace();
在我的主要方法中,我调用了 game.start() 方法。 但是每当我运行这段代码时,图片的移动都非常滞后。 我的动作非常流畅,但每隔一秒左右就会出现一些滞后。 我认为问题出在“runtick()”方法中。 有谁知道为什么会这样? 我希望你们中的一些人可以帮助我;D
【问题讨论】:
【参考方案1】:您正在增加游戏的睡眠时间,具体取决于游戏逻辑所需的时间。您要做的是根据游戏逻辑所需的时间减少睡眠。
您还需要将渲染时间包括在计算中(在很多游戏中,这可能会很快超过游戏逻辑时间)。试试这样的:
long delta, end, start = System.currentTimeMillis();
while (running)
runtick();
runrender();
end = System.currentTimeMillis();
delta = (end - start);
Thread.sleep((1000 / fps) - delta);
start = end;
如果您发现delta
变得大于滴答间隔(1000 / fps)
,则应记录一些警告并缓解问题,您可以在每个渲染滴答中运行多个游戏逻辑滴答,以使游戏逻辑赶上动画。
【讨论】:
@Luap555 如果要在 while 循环的开头重新分配start
,则可以删除行 start = end;
。我添加了start = end;
以减少对System.currentTimeMillis()
的调用量
感谢您的快速回答,如果我添加 if(delta > (1000 / fps)
,这个 if 语句应该做什么?因为只是一个错误警告没有帮助,我猜。目前画面还没有完全流畅地移动。
如果发生这种情况,您可能需要降低 FPS。作为解决问题的方法(实际上是一种解决方法……这需要权衡取舍)是为游戏逻辑运行额外的“滴答声”。 while(delta > (1000 / fps)) runtick(); delta -= (1000 / fps);
以上是关于为啥这个游戏循环滞后?的主要内容,如果未能解决你的问题,请参考以下文章
来自 lockCanvas 方法的游戏循环中的偶尔卡顿/滞后