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

Posted

技术标签:

【中文标题】试图理解 Java 中的高级游戏循环【英文标题】:Trying to understand an advanced game loop in Java 【发布时间】:2013-12-29 15:23:11 【问题描述】:

我正在开发一个简单的 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 的恒定游戏速度”下的文章中找到此循环。

我的问题是,我不完全理解它。我阅读了文章中的描述,了解到这个游戏循环可能最适合我的游戏,但并不完全理解它是如何工作的。

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

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

感谢您的帮助

【问题讨论】:

对不起,这个网站的新手。忘记接受答案。从现在开始会做:) 为什么要等待未来?您没有理由不接受旧答案。 【参考方案1】:

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

首先定义游戏循环:

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 时间。

【讨论】:

【参考方案2】:

next_game_tick 存储假设下一个游戏滴答发生的时刻。 你有两个不同的时间。您可以使用 System.currentTimeMillis() 获得的实时时间,以及等于 SKIP_TICKS 乘以循环的迭代次数加上游戏开始的时间的游戏时间。 在循环中调用更新方法,直到游戏时间赶上实际时间。每次调用 update_game 都会使游戏的“时钟”提前 SKIP_TICKS 毫秒。

【讨论】:

以上是关于试图理解 Java 中的高级游戏循环的主要内容,如果未能解决你的问题,请参考以下文章

《深入理解Java虚拟机:JVM高级特性与最佳实践》PDF下载

Java高级编程:深入理解Java虚拟机(值得收藏)

Java-Runoob-高级教程-实例-方法:09. Java 实例 – continue 关键字用法-un

高级变量类型(列表,元组,字典,字符串,公共方法,变量高级)for循环

深入理解Java虚拟机:JVM高级特性与最佳实践的内容简介

《深入理解Java虚拟机 - Jvm高级特性与最佳实践(第三版)》阅读笔记