java - 为什么这个游戏循环滞后?
问题描述
我对 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
解决方案
您正在增加游戏的睡眠时间,具体取决于游戏逻辑所需的时间。你想要做的是根据游戏逻辑需要多长时间来减少睡眠。
您还需要将渲染时间包括在计算中(在很多游戏中,这会很快变得大于游戏逻辑时间)。尝试这样的事情:
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)
,您应该记录一些警告并减轻您的影响,您可以在每个渲染滴答中运行多个游戏逻辑滴答,以使游戏逻辑赶上动画。
推荐阅读
- php - 为什么在案例 0 的 PHP SWITCH 中表现得如此愚蠢?
- c++ - 在 Visual Studio 中编码 C++ 时控制台窗口消失
- firebase - 颤动中特定设备的Firebase消息通知
- c# - asp.net core:“更改非并发集合的操作必须具有独占访问权限。”
- python - 软件包 libcxxabi 已安装但在 conda 中找不到
- sublimetext3 - 如何在 sublime 文本中更改 flake8 的缩进设置?
- apache-spark - 什么是 Spark 中的“序列化重定位”?
- java - 是否可以在 Java 的父类中为子类赋值?
- python - 根据先前 tkinter 条目小部件中给出的值添加条目小部件
- javascript - 更新嵌套对象