【问题标题】:Game Loop - Time Computation游戏循环 - 时间计算
【发布时间】:2014-12-15 11:40:34
【问题描述】:

在我的 Opengl“引擎”中,我有以下方法来计算所有时间值,我可能需要在一帧中:

public static void computeTime(){
    thisFrame = System.nanoTime();
    delta = thisFrame - lastFrame;
    lastFrame = thisFrame;
    deltams = (float) (delta / 1e6);
    deltas = (float) (delta / 1e9);
    fps = (float) 1e9 / delta;
    ticksInSeconds += deltas;
}

我在每一帧的开头调用这个方法。 然后我使用增量值来计算运动和事物。

这是执行此操作的正确方法吗?还是我在计算顺序上遗漏了一些东西?因为我觉得运行应用程序有点滞后......所以它不可能完全正确,不是吗?

【问题讨论】:

  • 可能System.currentTimeMillis 可以为您节省一些性能并且不会不准确。
  • 我不认为 nanoTime() 比 currentTimeMillis() 慢很多...
  • @cy3er:两者都有点不准确,不幸的是,Java 保证这些计时器是单调的。在某些情况下,它们可能会在短时间内倒退。然而,在这两者中,nanoTime (...) 遇到问题的可能性较小 - NTP 时间同步不会突然将计时器使用的时钟设置回 1-5 秒。
  • delta 是什么类型。如果它是整数类型,那么deltas 可能总是为零,并且在非常高的帧速率下deltams 会浪费大量时间。
  • delta 是一个浮点数,别担心。

标签: java opengl lwjgl game-engine game-loop


【解决方案1】:

编辑

显然计时器并不总是像您期望的那样工作。请查看此线程中提供的其他答案。

原答案

就我个人而言,我会使用逐帧的固定移动,而不是基于自上一帧以来经过的时间的可变移动。

要实现这一点,您需要像update() 这样的方法来更新所有位置并绘制更新后的视图,然后使用计时器定期调用此方法:

Timer timer;
final int FPS = ... //Number of frames per second
final int MS_BETWEEN_UPDATES = 1000/FPS;

ActionListener updater = new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        update();
    }
};

void update() {
    //Update your game here
}

void startGame() {
    timer = new Timer(MS_BETWEEN_UPDATES, updater);
    timer.start();
}

【讨论】:

  • 但我想拥有我能达到的最大帧率。
  • @T_01 但是你是怎么计算的呢?在某些时候,系统需要能够将您的图形推送到硬件管道,但如果系统要处理这些更新,它将开始作呕,并且会停止或丢弃内容以跟上.
  • 不要使用计时器来计时关键的事情,我已经测试它们最多延迟十五毫秒。
  • 嗯,我曾经在一个简单的 Snake 游戏中使用过这个概念,它运行良好,但我想如果你正在运行更重或更多依赖时间的任务,你可能会遇到麻烦。我已经编辑了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-07
相关资源
最近更新 更多