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

时间:2011-12-03 02:47:51

标签: java timer

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

java.util.Timer bulletTimer= new java.util.Timer();
bulletTimer.schedule(new bulletTimerTask(), 0, 2);

我也试过javax.swing.timer并遇到了同样的问题。任何帮助将不胜感激。

编辑:它适用于另一个定时器,我将延迟设置为2000毫秒

2 个答案:

答案 0 :(得分:2)

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

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

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

distance_for_dt = speed * delta_time
new_position = old_position + distance_for_dt

这将解决给定系统的各种波动 - 不同的系统负载,进程争用,CPU功率节流,月相等 - 以及使速度在不同计算机上保持一致。

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

快乐的编码。


随着BizzyDizzy的推出,System.nanoTime可用于计算时间增量。 (System.currentTimeMillis和时钟更改存在一些微妙的问题。)

答案 1 :(得分:0)

您可以使用Java 5附带的System.nanoTime(),它是Java中最高分辨率的计时器。它以纳秒为单位提供值。