2015-10-30 64 views
-1

完整代码:https://github.com/Sheldor5/JavaGPP(见测试两个选项)Java - 太快无法识别?

我有命令模式和循环一些奇怪的行为(递减​​计数,直到应执行的实际命令动作):

我试图实现:

我目前正在开发一款游戏,在这个游戏中我想放置一个“炸弹”,这个“炸弹”应该在例如2秒。我这样做的命令模式,其中一种类型的命令减去timeLeft变量的delta直到timeLeft变量为< =零 - >如果2秒过去了,爆炸应该发生。如果我在while循环中执行命令,这是行不通的,因为炸弹在+2.2秒后爆炸,而不是在2(和一些毫微秒)之后爆炸。如果我在循环中添加Thread.sleep(1),那么对我来说时间就足够准确,所以我可以说delta的计算已经完成了。

选项1:

// infinite loop: execute all commmands in the executor (only one command for now) 
while (true) { 
    commandExecutor.executeCommands(); 
} 

// the only one command in the executor gets called everytime 
public static final long NANOS = 1000000000; 

private long timeLeft = NANOS; 
private long start; 

public Command() { 
    this.start = System.nanoTime(); 
} 

public execute(final long delta) { 
    this.timeLeft -= delta; 
    if (this.timeLeft <= 0) { 
     final long time = System.nanoTime() - this.start; 
     System.out.println(String.format("Successfully executed Command with ID '%s' in %dns (%dns)", this.getID(), time, this.timeLeft)); 
     this.timeLeft += NANOS; 
    } 
} 

预期输出(1秒间隔):

成功地与ID在1000000454ns '1' 执行的命令(-454ns)

在1000000695ns(-695ns)内成功执行ID为1的命令

成功地与ID在1000000549ns '1' 执行的命令(-549ns)

成功地与ID在1000000003ns '1' 执行的命令(-3ns)

实际输出():

成功执行的命令ID为在1267062727ns '1'(-266ns)

成功地与ID在1350811695 '1' 执行的命令纳秒(-165ns)

成功地与ID在1352353549ns '1' 执行的命令(-145ns)

成功地与ID在1263098003ns '1' 执行的命令(-75ns)

但是,如果我添加Thread.sleep()进入循环的实际输出是精确得多:

选项2:

while (true) { 
    commandExecutor.executeCommands(); 
    try { 
     Thread.sleep(1); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

可接受的输出:

成功地与ID在1000015964ns '40' 执行Command4(-47338ns)

成功地与ID在1001095472ns '40' 执行Command4(-316309ns)

在1000039457ns(-224116ns)内成功执行ID为40的Command4

在1001043666ns(-662982ns)中成功执行ID为40的Command4(-662982ns)

有人可以向我解释这一点吗?循环太快了吗?速度如此之快以至于无法识别变量的实际值,并且错误地认为它大于零?为什么有这么大的差异,从那里〜0.2秒?

+3

很难跟踪你实际尝试做什么。你能详细说明吗? – Thomas

+0

我将更新问题 – Pali

+0

为什么您只在使用公式中的'this.start' *后已经在公式中使用?那应该是下一个命令的开始时间吗? – Siguza

回答

0

最初我以为这是一个并发问题,但我不认为这是因为您的自定义执行程序和命令不产生任何新线程。相反,我认为你只是把你的时间花费太多。你的代码基本上只是循环播放,并呼吁System.nanotime()。使用变量delta的方法存在的问题是,您没有考虑调用System.nantime()时涉及的时间。但是你会说很多。我认为使用计时器任务将是更可取的,但如果你想自己做这样的事情,请尝试类似以下内容:

long start = System.nanotime(); 
long inTwoSecs = start + 2000000000L; 
while (true) { 
    long now = System.nanotime(); 
    if (now >= inTwoSecs) { 
     return; 
    } 
} 
+0

好的,但是然后命令在现在+ 2秒内执行,而不是在2秒内播放时间(暂停和恢复)^^但我想我需要找到另一种方式来处理这个问题。 – Pali

+0

@Pali你可以做类似的事情,但有一个方法。 getGameTime,并适当更新。你的例子中的while循环会旋转一段时间,但它也与你的游戏时间无关。 – matt

+0

@matt不,因为我在未来处理nanos与delta - 这与游戏时间有关^^ – Pali