问题描述
如果我无法控制我的代码每秒执行的次数,那么当我添加一行时,程序会有所不同,因此我必须再次调整常量。 (由Google翻译) 我的代码失控了:
public builder(){
while(true)
stepEvent();
}
private void stepEvent() {
setofActions();
repaint();
}
解决方法
import java.util.Timer;
import java.util.TimerTask;
public class HelloWorld {
public static void main(String []args) {
// number of ms in 1/60 of a second
// there will be some rounding error here,// not sure if that's acceptable for your use case
int ms = 1000 / 60;
Timer timer = new Timer();
timer.schedule(new SayHello(),ms);
}
}
class SayHello extends TimerTask {
public void run() {
System.out.println("Hello World!");
}
}
,
这只是做到这一点的一种方法(虽然时间很长,但非常精确-我建议将其用于游戏开发)。在这种情况下,我使用了Runnable接口中的run()
方法来执行代码。
public void run(){
long lastTime = System.nanoTime();
final double ns = 1000000000.0 / 60.0;
double delta = 0;
while(true){
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while(delta >= 1){
the code you want to be executed
delta--;
}
}
}
逐行说明:
基本上,我将当前时间(以纳秒为单位)存储在lastTime
中。然后在ns
中存储1/60秒(以纳秒为单位),并创建一个变量delta
。
此后,我进入了无限while循环(不一定是无限循环),并将当前时间(以纳秒为单位)再次存储在now
中。这是考虑到计算机从lastTime
声明行转到while循环行所花费的时间。
完成所有这些操作后,我将delta
和now
之差除以我提到的1/60秒(lastTime
)。这意味着每次ns
等于1时,将经过1/60秒。
此后,我使delta
与lastTime
相同。在随后的while循环中,我检查增量是否等于或大于1,然后在其中应将每秒要执行的所有代码放置60次。不要忘记从now
中减去1,这样就不会无限循环。
彻底分析代码,看是否能理解。如果不能,我将进一步说明。我坚持认为这只是一种可行的方法,但是还有更多的方法。
注意:在某些情况下,您甚至都不需要delta
,但这对某些用途很有帮助。
该代码的信誉:该代码的大部分(至少是在我获得和获得它的地方)是从TheCherno's Game Programming Series提取的
祝你有美好的一天!
,要在定义的时间段内停止执行,可以使用Thread.sleep(millis,nanos)
for(;;){
stepEvent();
Thread.sleep(100);
}
否则,您可以使用ScheduledExecutorService
来安排代码在指定的延迟后或以固定的时间间隔运行一次。
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(YourClass::stepEvent,100,TimeUnit.MILLISECONDS);