我正在使用java.util.timer来编写一个我正在编程的游戏来增加JLabel的位置,但它通常比我需要它慢得多。有时它会以正确的速度运行,但无论如何,下次执行程序时它会再次变慢。我使用以下代码作为计时器。
java.util.Timer bulletTimer= new java.util.Timer();
bulletTimer.schedule(new bulletTimerTask(), 0, 2);
我也试过javax.swing.timer并遇到了同样的问题。任何帮助将不胜感激。
编辑:它适用于另一个定时器,我将延迟设置为2000毫秒
答案 0 :(得分:2)
由于您正在移动JLabel
,我实际上会继续使用(单个)swing.Timer
。这样做的原因是回调总是“在EDT上”发生,因此可以访问Swing组件。 (如果您使用util.Timer
,那么更新应该发布/排队到EDT,但这需要更多一些。)
现在,请记住,util.Timer
和swing.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中最高分辨率的计时器。它以纳秒为单位提供值。