2013-02-19 94 views
0

我正在使用JavaScript支持的canvas元素构建游戏。我的球员类的一部分包括一个update()方法,该方法每次打勾调用一次。在这种方法中,我正在做一些数学运算来根据键盘输入来更新球员速度,并且还要移动球员。下面是代码的一块:获得更准确的浮点计算

// Gradually make the players velocity 0 
if(this.xv > 0) { 
    this.xv -= 0.1; 
} else if(this.xv < 0) { 
    this.xv += 0.1; 
} 
if(this.yv > 0) { 
    this.yv -= 0.1; 
} else if(this.yv < 0) { 
    this.yv += 0.1; 
} 

// Update player position based on velocity 
this.x += this.xv; 
this.y += this.yv; 

// Update velocity based on keyboard inputs 
if(keyState[87]) { 
    this.yv -= 0.5; 
} 
if(keyState[65]) { 
    this.xv -= 0.5; 
} 
if(keyState[83]) { 
    this.yv += 0.5; 
} 
if(keyState[68]) { 
    this.xv += 0.5; 
} 

现在,在理论上这应该一切工作正常,如果玩家按住4 W键蜱它们的速度会2,再经过40多个蜱它们的速度会减至0

尽管这在实际中并不适用,因为JavaScript在处理浮点数时似乎并不完全准确。如果我console.log()速度变量每场比赛蜱我得到这样的输出:

x: -1.0241807402167069e-14   y: -1.379452108096757e-14 
x: 0.09999999999998976   y: 0.09999999999998621 
x: -1.0241807402167069e-14   y: -1.379452108096757e-14 
x: 0.09999999999998976   y: 0.09999999999998621 

因此,有是错在这里看两个东西,一个是JavaScript的从未计算精度良好的速度,另一个是当速度是负的,它始终至少为-1,这是一个问题,因为玩家精灵现在将以每个打勾1个像素移动。

如何为此任务获得更准确的计算结果?

+0

从这里开始您的研究:[用于JavaScript浮点数问题的优雅解决方法](http://stackoverflow.com/a/3439981/612202) – 2013-02-19 21:03:57

+0

我是“指数衰减”方法的放大粉丝;我会用'this.xv * = 0.9替换你的第一个if块; this.yv * = 0.9;'(或任何因素“感觉”最好)。避免舍入误差后速度在零附近振荡的问题。 – 2013-02-19 21:06:38

+0

@XavierHolt:实际上大多解决了这个问题。我仍然以'-0.000021784715049668016'这样的数字结束,但为了我的目的,这很好,我只是想避免这个精灵显着地“爬行”。如果您将此添加为答案,我会接受它。 – 2013-02-19 21:10:10

回答

1

我推荐使用“指数衰减”方法来平滑你的速度转换。相反,你目前使用的速度降低到零的条件块的,我会用以下内容:

this.xv *= 0.9; 
this.yv *= 0.9; 

注意,这十倍的恒定加速度帽的最大速度,并改变衰减率将改变乘数。这可能是正确的,但如果没有的话,你可以调整公式,以缓解为目标速度:

var p = 0.9; 
var q = 1.0 - p; 
this.xv = this.xv * p + this.txv * q; 
this.yv = this.yv * p + this.tyv * q; 

免责声明:这在牛顿物理学没有真正的依据;这只是我想出来的,以帮助消除机器人中的状态转换。但它对我很好,也希望能为你服务。