【问题标题】: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

【问题讨论】:

    标签: java game-loop


    【解决方案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);}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    相关资源
    最近更新 更多