java.util.Timer-事件之间的速度不一致?

java.util.Timer-事件之间的速度不一致?,java,timer,Java,Timer,我正在为一个游戏使用java.util.timer,我正在编程该游戏以增加JLabel的位置,但它通常比我需要的速度慢得多。有时它会以正确的速度运行,但下一次我执行程序时,它会毫无原因地再次变慢。我使用以下代码作为计时器 java.util.Timer bulletTimer= new java.util.Timer(); bulletTimer.schedule(new bulletTimerTask(), 0, 2); 我还尝试了javax.swing.timer,但遇到了同样的问题。任何

我正在为一个游戏使用java.util.timer,我正在编程该游戏以增加JLabel的位置,但它通常比我需要的速度慢得多。有时它会以正确的速度运行,但下一次我执行程序时,它会毫无原因地再次变慢。我使用以下代码作为计时器

java.util.Timer bulletTimer= new java.util.Timer();
bulletTimer.schedule(new bulletTimerTask(), 0, 2);
我还尝试了javax.swing.timer,但遇到了同样的问题。任何帮助都将不胜感激


编辑:它可以与另一个计时器配合使用,我将延迟设置为2000毫秒。您可以使用Java 5附带的System.nanoTime(),它是Java中分辨率最高的计时器。它以纳秒为单位提供值。

因为您正在移动
JLabel
,所以我实际上会继续使用(单个)
swing.Timer
。这是因为回调总是“在EDT上”发生,因此可以访问Swing组件。(如果您使用的是
util.Timer
,那么更新应该被发布/排队到EDT,但这需要更多的参与。)

现在,请记住,
util.Timer
swing.Timer
没有保证的计时(除了“将至少X长”),为此,重要的是要考虑“时间增量”(自上次更新发生以来的时间)

这是在文章中讨论的,虽然这篇文章是关于一个简单的游戏循环而不是计时器的,但同样的概念也适用。要获得固定速度(无加速度)的一致更新模式,只需使用:

distance_for_dt = speed * delta_time
new_position = old_position + distance_for_dt
这将解释给定系统上的各种波动——不同的系统负载、进程争用、CPU功率限制、月相等——并使不同计算机的速度保持一致

熟悉基本位置更新后,可以使用更“高级”的离散公式进行更精确的定位,包括考虑加速度的公式

快乐编码



Bizzydizy指出,
System.nanoTime
可以用来计算时间增量。(System.currentTimeMillis和时钟变化有一些微妙的问题。)

不要为此使用计时器——至少不要为每个项目符号/对象使用计时器。相反,要有一个计时器(手动,例如,一个有产量的循环,或其他),并根据经过的时间的增量完成所有工作。,,这如何使计时器更精确?回答:没有。事实上,这对OP没有帮助,因为如果他的计时准确到微秒,他会很高兴。解决方案由pst发布。