如果我不知道每秒 运行 有多少次,我怎样才能得到相同的输出?
If I don't know how many times something will run per second, how can I get the same output?
所以我有一个变量attemptedFPS
。这是我的循环每秒 运行 的次数。
示例循环:
setInterval(console.log, 1000/attemptedFPS, "Hello World");
因此,例如,如果 attemptedFPS
设置为 50,则该循环将每 20 毫秒 运行(加起来为 50/秒)。
我的问题是无论 attemptedFPS
设置成什么,输出都是一样的。我想每秒添加一个变量 speed
到 x
。 (即,如果 speed
设置为 10,则意味着每秒向 x
添加 10)。
所以,如果在那个循环中,我有:
setInterval(function(){
x += speed;
}, 1000/attemptedFPS);
现在,当然,根据 attemptedFPS
会产生不同的结果。
无论 attemptedFPS
是多少,每秒将 speed
添加到 x
的公式是什么?
这将确保 x 每秒增加 speed
,考虑到自上次触发间隔以来经过的毫秒数。例如,如果间隔在 100 毫秒前触发,那将是十分之一秒,这意味着我们将 speed * .1
添加到 x
。
let then = Date.now()
setInterval(function(){
const timeSinceLastFrame = Date.now() - then;
then = Date.now()
x += speed*timeSinceLastFrame/1000;
}, 1000/attemptedFPS);
这是必要的,因为不能保证间隔恰好每隔 'frame' 执行一次,它只能保证至少 1000/attemptedFPS
毫秒后函数才会在事件循环中排队。方差很容易超过一毫秒,这意味着简单的算术不会让你到达那里。因此,我们实际上是检查函数触发的时间,以决定 x
应该获得多少速度。
- add
speed
to x
by every second.
- whatever the function execute how many times (also by every second).
这可能是一道基础数学题。答案很简单:
Divide the speed
variable to attemptedFPS
pieces.
因为它会被添加回您的循环中。
测试一下,这个循环会运行1000/attemptedFPS
次,不管你把attemptedFPS
设置成什么,结果总是x += speed
(以10为例).
for (let i = 0; i < 1000; i += 1000/attemptedFPS) {
x += speed / attemptedFPS;
}
// result: 9.999999999999996;
但是如您所见,它应该正好是 10
。这是因为JavaScript中的浮点精度问题。我建议 Number.toPrecision())
来处理这个问题,但它应该有效。
for (let i = 0; i < 1000; i += 1000/attemptedFPS) {
x += speed / attemptedFPS;
x = +parseFloat(x.toPrecision(12));
}
// result: 10;
所以,回答你的问题:
setInterval(function(){
x += speed / attemptedFPS;
x = +parseFloat(x.toPrecision(12));
}, 1000/attemptedFPS);
所以我有一个变量attemptedFPS
。这是我的循环每秒 运行 的次数。
示例循环:
setInterval(console.log, 1000/attemptedFPS, "Hello World");
因此,例如,如果 attemptedFPS
设置为 50,则该循环将每 20 毫秒 运行(加起来为 50/秒)。
我的问题是无论 attemptedFPS
设置成什么,输出都是一样的。我想每秒添加一个变量 speed
到 x
。 (即,如果 speed
设置为 10,则意味着每秒向 x
添加 10)。
所以,如果在那个循环中,我有:
setInterval(function(){
x += speed;
}, 1000/attemptedFPS);
现在,当然,根据 attemptedFPS
会产生不同的结果。
无论 attemptedFPS
是多少,每秒将 speed
添加到 x
的公式是什么?
这将确保 x 每秒增加 speed
,考虑到自上次触发间隔以来经过的毫秒数。例如,如果间隔在 100 毫秒前触发,那将是十分之一秒,这意味着我们将 speed * .1
添加到 x
。
let then = Date.now()
setInterval(function(){
const timeSinceLastFrame = Date.now() - then;
then = Date.now()
x += speed*timeSinceLastFrame/1000;
}, 1000/attemptedFPS);
这是必要的,因为不能保证间隔恰好每隔 'frame' 执行一次,它只能保证至少 1000/attemptedFPS
毫秒后函数才会在事件循环中排队。方差很容易超过一毫秒,这意味着简单的算术不会让你到达那里。因此,我们实际上是检查函数触发的时间,以决定 x
应该获得多少速度。
- add
speed
tox
by every second.- whatever the function execute how many times (also by every second).
这可能是一道基础数学题。答案很简单:
Divide the
speed
variable toattemptedFPS
pieces.
因为它会被添加回您的循环中。
测试一下,这个循环会运行1000/attemptedFPS
次,不管你把attemptedFPS
设置成什么,结果总是x += speed
(以10为例).
for (let i = 0; i < 1000; i += 1000/attemptedFPS) {
x += speed / attemptedFPS;
}
// result: 9.999999999999996;
但是如您所见,它应该正好是 10
。这是因为JavaScript中的浮点精度问题。我建议 Number.toPrecision())
来处理这个问题,但它应该有效。
for (let i = 0; i < 1000; i += 1000/attemptedFPS) {
x += speed / attemptedFPS;
x = +parseFloat(x.toPrecision(12));
}
// result: 10;
所以,回答你的问题:
setInterval(function(){
x += speed / attemptedFPS;
x = +parseFloat(x.toPrecision(12));
}, 1000/attemptedFPS);