试图理解Java中的高级游戏循环

时间:2013-12-29 15:23:11

标签: java multithreading game-loop

我正在开发一个简单的Java 2D游戏。

我为游戏写了一个游戏循环。使用这个游戏循环,游戏有时以中等(不变,我认为)速度运行,有时当我启动它时,它以慢速(恒定)速度运行。

我学会了从以下文章实现这个游戏循环:Here

这是代码:

(我把它的代码改为Java。你可以在文章“FPS依赖恒定游戏速度”下找到这个循环。)

public void run(){

    next_game_tick = System.currentTimeMillis();

    while(true){

        updateGame(); // This is actually a bunch of methods.

        repaint();

        next_game_tick = next_game_tick + skip_ticks;
        sleep_time = next_game_tick - System.currentTimeMillis();

        if(sleep_time<0)sleep_time=2;
        try {
            Thread.sleep(sleep_time);
        } catch (InterruptedException e) {}

        next_game_tick = System.currentTimeMillis();

    }

}

正如我所说,这个循环并不总是以适当的速度运行游戏,所以我看了上面文章中建议的其他游戏循环实现。

以下实现仅基于其描述,似乎最适合我的游戏:

int TICKS_PER_SECOND = 50;
int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
int MAX_FRAMESKIP = 10;

long next_game_tick = System.currentTimeMillis();
int loops;

bool game_is_running = true;
while( game_is_running ) {

    loops = 0;
    while( System.currentTimeMillis() > next_game_tick && loops < MAX_FRAMESKIP) {
        update_game();

        next_game_tick += SKIP_TICKS;
        loops++;
    }

    repaint();
}

(我把它的代码改为Java。你可以在文章“恒定游戏速度和最大FPS”下找到这个循环。)

我的问题是,我不完全理解它。我在文章中读到了它的描述,并且明白这个游戏循环可能对我的游戏来说是最好的,但是并不完全理解它是如何工作的。

如果有人向我解释这个游戏循环,我会很感激,所以在尝试在我的游戏中实现它之前我会完全理解它。

(编辑:我理解游戏循环的概念及其工作原理,但不是这个游戏循环特定及其所做的一切)。

感谢您的帮助

2 个答案:

答案 0 :(得分:2)

你发现的游戏循环实际上已经过时了。您可能想要搜索更新的教程。对于您的游戏,请尝试以下方法:

首先定义游戏循环:

class GameLoop extends Runnable {
  public void run() {
    updateGame();
    repaint();
  }
}

并称之为:

static final long TARGET_FPS = 60;
static final long TICK_RATE = 1000 / TARGET_FPS;

// ... in main:
final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(new GameLoop(), TICK_RATE, TimeUnit.MILLISECONDS);

您的GameLoop现在将按照请求进行调用,而不会在等待时浪费CPU时间,您可以在scheduleAtFixedRate的文档中找到更多信息。 如果使用正确的Java类,编码通常会变得更容易。

作为旁注:如果没有将更新提取到屏幕,则无需更新游戏。您应该尝试将计算编码为不需要中间步骤,因为这只会浪费CPU时间。

答案 1 :(得分:0)

next_game_tick存储下一个游戏节拍的发生时刻。 你有两个不同的时间。使用System.currentTimeMillis()获得的实时时间,以及等于SKIP_TICKS的游戏时间乘以循环的迭代次数加上游戏开始的时间。 在循环中,调用更新方法,直到游戏时间赶上实时。每次调用update_game都会通过SKIP_TICKS ms推进游戏的“时钟”。