Blender Game Engine中使用IF函数的意外行为

时间:2015-05-10 19:19:29

标签: python if-statement game-engine blender

我正在研究BGE中的一个项目,当我按下按钮时,我想让物体慢慢加速到最大速度。当我按下另一个按钮时,它应该减速然后再慢慢加速到另一个方向的最高速度。

以下是代码:

import bge

cont = bge.logic.getCurrentController()
own = cont.owner
keyboard = bge.logic.keyboard
ACTIVE = bge.logic.KX_INPUT_ACTIVE
INACTIVE = bge.logic.KX_INPUT_NONE
accelerate = own['accelerateProp']

accelerateFactor = 0.005

own.applyMovement((0, accelerate, 0))

if(keyboard.events[bge.events.WKEY] == ACTIVE and accelerate > -0.05):
    own['accelerateProp'] -= accelerateFactor

if(keyboard.events[bge.events.SKEY] == ACTIVE and accelerate < 0.05):
    own['accelerateProp'] += accelerateFac

我有一个accelerateProp属性的对象,我用它来控制对象的速度。

当我按住W键时,它会加速。但不是停在-0.05,而是再次运行一次,它停在-0.055。如果我按住S按钮,它会减速,然后再次加速并停在0.05。

令人困惑的是,如果我先拿着S键,它会加速到0.055,反之亦然。

所以实际上,将达到最高速度冷杉的方向将被打破而另一方将会很好并且它将保持这种状态,因此一方将始终具有最大速度0.055和另一方0.05。

我无法理解错误。我怀疑它必须做一些有游戏属性的东西,但我真的不知道。如果还有另一种做法,请告诉我。

谢谢!

2 个答案:

答案 0 :(得分:2)

如果没有更多信息,很难确定,但我几乎可以肯定这只是一个典型的浮点舍入错误。

考虑这段代码(它实际上与你的代码做同样的事情,但中间没有所有用户交互的东西):

x = 0
while x < 0.05:
    x += 0.005
print(x)

您认为结果会是0.05,对吗?但事实并非如此。它是0.05499999999999999。为什么它走得太远?

如果您沿途打印出所有值,原因很明显:

0.005
0.01
0.015
0.02
0.025
0.030000000000000002
0.035
0.04
0.045
0.049999999999999996
0.05499999999999999

没有浮点双精确等于所有这些数字,因此累积舍入误差。当你到达第10个时,它不是0.05,而是0.049999999999999996,它仍然小于0.05,所以它又向前迈了一步。 / p>

这样的问题有两种解决方案。

首先,您可以使用Decimal代替float。当然,Decimal同样不精确,并且一般会受到float的舍入误差的影响;区别在于具有精确十进制字符串表示的任何数字(如0.005和所有其他值)也具有精确的Decimal表示。所以:

from decimal import Decimal
x = Decimal('0')
while x < Decimal('0.05'):
    x += Decimal('0.005')
print(x)

现在您获得0.05而不是0.05499999999999999

或者,您可以使用绝对或相对epsilon比较。例如:

eps = 1e-5

while x + eps < 0.05:
    x += 0.005
print(x)

现在,您最终得到0.049999999999999996而不是0.05499999999999999

答案 1 :(得分:0)

完善您的财产。 josephus(n - 1, k) - 1 2是圆点。