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;
}

现在理论上这一切都可以正常工作,如果玩家按住 W 键 4 刻,他们的速度将是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 个像素的速度移动打钩。

我怎样才能为这项任务获得更准确的计算?

4

1 回答 1

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;

免责声明: 这在牛顿物理学中没有真正的基础;这只是我想出的帮助平滑机器人状态转换的方法。但这对我很有用,希望对你也有用。

于 2013-02-19T21:31:52.287 回答