5

我正在用 Java 编写一个模拟,其中对象在牛顿物理学下起作用。一个物体可能会被施加一个力,并且产生的速度会导致它在屏幕上移动。模拟的性质意味着对象以离散的步骤移动,具体取决于动画循环的当前迭代和上一次迭代之间经过的时间;例如

public void animationLoop() {
  long prev = System.currentTimeMillis();
  long now;

  while(true) {
    long now = System.currentTimeMillis();
    long deltaMillis = now - prev;
    prev = now;

    if (deltaMillis > 0) { // Some time has passed
      for (Mass m : masses) {
        m.updatePosition(deltaMillis);
      }

      // Do all repaints.
    }
  }
}

如果动画线程以某种方式延迟导致大量时间流逝(典型情况是在 Windows 下单击并按住最小化/最大化防止重绘),则会出现问题,这会导致对象以惊人的速度移动。我的问题:有没有办法确定在动画线程中花费的时间而不是挂钟时间,或者任何人都可以建议一种解决方法来避免这个问题?

到目前为止,我唯一的想法是限制deltaMillis某个上限。

4

4 回答 4

6

您是否考虑过使用计时器之类的东西而不是循环旋转?

TimerTask tt = new TimerTask(){
  long prev = System.currentTimeMillis();
  public void run(){
    long now = System.currentTimeMillis();
    for (Mass m : masses) {
      m.updatePosition(now-prev);
    }
    prev = now;
  }
}

new Timer(true).schedule(tt, 1000, 1000) ;

这样,您可以保证至少在对象更新之间有一些延迟,因此您不应该像 while(true) 循环那样连续进行一堆重绘,如果线程被延迟,您将不会立即得到重新-任务的执行,来自文档:“在固定延迟执行中,每次执行都是相对于前一次执行的实际执行时间安排的。”

于 2010-04-14T12:22:46.720 回答
3

我发现javax.swing.Timer.html对此特别有帮助。这是一个模拟球形粒子和容器壁之间的弹性碰撞的示例。

附录:这种相关方法可能有助于将模型与视图分离。一个单独的线程对系统的演变进行建模,而视图以固定速率呈现模型的“快照”。

无论哪种情况,我都会限制速率以适应最慢的目标平台。

于 2010-04-14T14:43:35.427 回答
1

您可能想阅读这篇题为“Java:使用 ThreadMXBean 获取线程时间”的文章。

基本上,有一个类ThreadMXBean可以让您获得特别花费的时间Thread。我还没有尝试过,但是这些方法(以及我提到的文章中的示例)看起来很有希望,所以我认为你将能够通过它完成你想要的。

于 2010-04-15T11:17:09.043 回答
0

我会使用动画库来制作动画,而不是重新发明轮子。这里有两个不错的选择:

于 2010-07-27T01:49:01.470 回答