我正在用Java编写一个模拟,其中对象在牛顿物理学下运作。物体可以施加力,并且所产生的速度使其在屏幕上移动。模拟的本质意味着对象根据动画循环的当前和上一次迭代之间的时间间隔以不连续的步骤移动; e.g
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
限制在某个上限。
答案 0 :(得分: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)循环一样连续重复一遍,如果线程被延迟,你就不会得到从文档中立即重新执行任务:“在固定延迟执行中,每次执行都是相对于上一次执行的实际执行时间进行调度的。”
答案 1 :(得分:3)
我发现javax.swing.Timer.html
对此特别有帮助。这是一个example,用于模拟球形颗粒与容器壁之间的弹性碰撞。
附录:此相关approach可能有助于将模型与视图分离。一个单独的线程模拟系统的演变,而视图以固定的速率呈现模型的“快照”。
在任何一种情况下,我限制费率以适应最慢的目标平台。
答案 2 :(得分:1)
您可能希望阅读名为“Java:使用ThreadMXBean获取线程时间”的article。
基本上,有一个班级ThreadMXBean可让您花时间在特定Thread
上。我没有尝试过,但方法(以及我提到的文章中的例子)看起来很有希望,所以我认为你将能够用这个完成你想要的东西。
答案 3 :(得分:0)
我会使用动画库来制作动画,而不是重新发明轮子。以下是两个不错的选择: