我想为Pong克隆创建一个开始菜单,其中背景中的球从边缘反弹。但是,游戏循环更新为快速,因此球的坐标已经在JFrame之外,您才能看到它,并且它会快速移动。我通过sysouts发现了这一点。
我想这与线程有关,但我不确定。 主类将该类称为线程,但重要的部分在类BackgroundBallMovement
中package main;
public class BackgroundBallMovement implements Runnable{
private boolean running = true;
@Override
public void run() {
long lastTime = System.nanoTime();
final double ns = 1000000000.0 / 60;
double delta = 0;
while(running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
while(delta >= 1) {
update();
delta = 0;
System.out.println("X-Koordinate " + Var.ballX + " " + "Y-Koordinate " + Var.ballY);
}
render();
}
}
//Spiellogik updaten
private synchronized void update() {
Var.ballX += 1;
Var.ballY += 1;
}
//Objekte zeichnen
private synchronized void render() {
Var.drawStartMenue.repaint();
}
}
答案 0 :(得分:1)
您没有使用Thread.sleep()。相反,您正在等System.nanoTime()更改。这意味着CPU一直在运行(不好)。
也是这个循环:
while(delta >= 1) {
...
delta = 0;
...
}
没有意义,因为可以用if代替它。
那么您就永远不会更新 lastTime 变量。所以这行:
delta += (now - lastTime) / ns;
将导致二次函数,因为它将导致如下所示(每次循环执行):
delta += 0.1;
delta += 0.2;
delta += 0.3;
...
然后,因为您永远不会在条件1s后更新 lastTime 变量
while(delta >= 1)
将始终满足您的要求,并且您的球将以惊人的速度移动。
您的第一种方法可能是这样的:
@Override
public void run()
{
while(running)
{
update();
render()
System.out.println("X-Koordinate " + Var.ballX + " " + "Y-Koordinate " + Var.ballY);
Thread.sleep(1000L/60L);
}
}
答案 1 :(得分:0)
那是因为您的数学很烂;-)
是的,aggregate(q~gender, transform(df, q = q01*2+q02), mean)
是引擎启动以来应该渲染的帧数。因此,您的代码可简化为:
(now - lastTime) / ns
等效于
while (true) {
delta = framesSinceStart();
while (delta >= 1) {
renderFrame();
delta = 0;
}
}
也就是说,您的代码正确地等待渲染第一帧,但是没有记录它已经渲染了该帧,因此始终认为它已经晚了,不再等待。
相反,您可以尝试类似的操作:
while (true) {
if (framesSinceStart() >= 1) {
renderFrame();
}
}
顺便说一句,仅仅停留在一个无休止的循环中来消磨时间并不是很省电。最好使用Thread.sleep()之类的东西等待-但是计算它应该手动等待的时间有点麻烦。幸运的是,Java API附带了很好的帮助程序类供使用:
while (true) {
if (framesSinceStart() - framesRendered >= 1) {
renderFrame();
framesRendered++;
}
}
答案 2 :(得分:0)
尝试Thread.sleep(long millis)
while(running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
while(delta >= 1) {
update();
delta = 0;
try{
Thread.sleep(1000);
} catch(Exception e) { }
System.out.println("X-Koordinate " + Var.ballX + " " + "Y-Koordinate " + Var.ballY);
}
render();
}
您还可以尝试降低球速。
private synchronized void update() {
Var.ballX += 0.01;
Var.ballY += 0.01;
}