JavaScript:如何计算移动精灵在';速度是相对于时间的吗?

JavaScript:如何计算移动精灵在';速度是相对于时间的吗?,javascript,math,canvas,html5-canvas,game-development,Javascript,Math,Canvas,Html5 Canvas,Game Development,我现在遇到了一个数学难题,已经困扰了我好几天了 我正在构建一个JavaScript游戏,并试图创建边界坐标来管理精灵的路径和移动,然而,延迟/抖动/延迟似乎正在对彼此协调移动的不同实体造成严重破坏 我相信我必须计算抖动/滞后/偏移,并以某种方式将其应用到坐标范围检测和移动功能中,但我尚未正确破解代码并缓解错误对齐的精灵 下面是CodeSandbox中该问题的复制,以及显示该问题的大部分代码: 但是我还没有把这个拿下来。提前非常感谢大家。首先,您的增量时间计算尚未完成 var now = Dat

我现在遇到了一个数学难题,已经困扰了我好几天了

我正在构建一个JavaScript游戏,并试图创建边界坐标来管理精灵的路径和移动,然而,延迟/抖动/延迟似乎正在对彼此协调移动的不同实体造成严重破坏

我相信我必须计算抖动/滞后/偏移,并以某种方式将其应用到坐标范围检测和移动功能中,但我尚未正确破解代码并缓解错误对齐的精灵

下面是CodeSandbox中该问题的复制,以及显示该问题的大部分代码:


但是我还没有把这个拿下来。提前非常感谢大家。

首先,您的增量时间计算尚未完成

var now = Date.now();
var delta = now - lastUpdate;
lastUpdate = now;
update(delta / 1000);
如果现在请求通过requestAnimationFrame调用
update()
,则作为参数传递的数字将是上一帧和当前帧之间传递的毫秒数。因此,如果屏幕刷新率为60hz,则大约为16.6ms

但仅此值没有意义-您需要将其与目标值进行比较

假设我们想要达到30fps的帧速率-等于~33.3ms。如果我们把这个值除以上面的16.6ms,我们得到大约0.5。这完全有道理。我们需要30fps,显示器以60hz刷新,所以所有东西都应该以一半的速度移动

让我们修改
main()
函数以反映:

 var main = function() {
   var targetFrameRate = 30;
   var frameTime = 1000 / targetFrameRate;
   var now = Date.now();
   var delta = now - lastUpdate;
   lastUpdate = now;
   update(delta / frameTime);
   render();
   requestAnimationFrame(main);
 };
第二个问题是
update()
函数本身。 让我们看一下下面的块:

if (direction === 0) {
  obj.x += obj.speed * modifier;
  ctx.clearRect(obj.x - 7, 9, 17, 17);
  ctx.fillRect(obj.x, 60, 15, 15);
}
这意味着,无论obj当前在哪里,都要将其向右移动一定量。我们错过了这一点的边界检查。如果我们将它移到右边,你需要检查它是否会离开边界。如果有,就把它移到边界旁边

大概是这样的:

var maxX=100;
 if (direction === 0) {
   var speed = obj.speed * modifier;
   if (obj.x + obj.width + speed > maxX) {
     direction = 1;
     obj.x = maxX - obj.width;
   } else {
     obj.x += speed;
   }
 }

首先,您需要注意,增量时间计算不完整

var now = Date.now();
var delta = now - lastUpdate;
lastUpdate = now;
update(delta / 1000);
如果现在请求通过requestAnimationFrame调用
update()
,则作为参数传递的数字将是上一帧和当前帧之间传递的毫秒数。因此,如果屏幕刷新率为60hz,则大约为16.6ms

但仅此值没有意义-您需要将其与目标值进行比较

假设我们想要达到30fps的帧速率-等于~33.3ms。如果我们把这个值除以上面的16.6ms,我们得到大约0.5。这完全有道理。我们需要30fps,显示器以60hz刷新,所以所有东西都应该以一半的速度移动

让我们修改
main()
函数以反映:

 var main = function() {
   var targetFrameRate = 30;
   var frameTime = 1000 / targetFrameRate;
   var now = Date.now();
   var delta = now - lastUpdate;
   lastUpdate = now;
   update(delta / frameTime);
   render();
   requestAnimationFrame(main);
 };
第二个问题是
update()
函数本身。 让我们看一下下面的块:

if (direction === 0) {
  obj.x += obj.speed * modifier;
  ctx.clearRect(obj.x - 7, 9, 17, 17);
  ctx.fillRect(obj.x, 60, 15, 15);
}
这意味着,无论obj当前在哪里,都要将其向右移动一定量。我们错过了这一点的边界检查。如果我们将它移到右边,你需要检查它是否会离开边界。如果有,就把它移到边界旁边

大概是这样的:

var maxX=100;
 if (direction === 0) {
   var speed = obj.speed * modifier;
   if (obj.x + obj.width + speed > maxX) {
     direction = 1;
     obj.x = maxX - obj.width;
   } else {
     obj.x += speed;
   }
 }
在碰撞过程中保持正确的速度 我注意到物体总是在移动,这意味着给定的答案不能正确地解决问题

如果对象具有恒定速度,则不应在帧之间减速

图中显示了一个正在移动的对象

  • 在顶部,它可以不间断地移动多远
  • 在碰撞点的中心。请注意,要保持相同的速度,还需要行驶很长的距离
  • 在底部,将对象向左移动剩余距离,以便总移动距离与速度匹配
要保持速度,帧之间行驶的总距离必须保持不变。将对象定位在碰撞点可以减少移动的距离,因此可以大大降低碰撞帧期间对象的速度

正确的计算如下

 const directions = {
     LEFT: 0,
     RIGHT: 1,
 };
 const rightWallX = 100;
 const leftWallX = 0;

 if (obj.direction === directions.RIGHT) {
     obj.x = obj.x + obj.speed;
     const remainDist = (rightWallX - obj.width) - obj.x;
     if (remainDist <= 0) {
         obj.direction = directions.LEFT;
         obj.x = (rightWallX - obj.width) + remainDist;
     }
 } else if (obj.direction === directions.LEFT) {
     obj.x = obj.x - obj.speed;
     const remainDist = leftWallX - obj.x;
     if (remainDist >= 0) {
         obj.direction = directions.RIGHT;
         obj.x = leftWallX + remainDist;
     }
 }
常量方向={
左:0,,
右:1,,
};
常数rightWallX=100;
常数leftWallX=0;
如果(对象方向===方向右){
obj.x=obj.x+obj.速度;
常量remainsit=(右墙x-对象宽度)-对象x;
如果(remainst=0){
obj.direction=directions.RIGHT;
对象x=左墙x+剩余部分;
}
}
在碰撞过程中保持正确的速度 我注意到物体总是在移动,这意味着给定的答案不能正确地解决问题

如果对象具有恒定速度,则不应在帧之间减速

图中显示了一个正在移动的对象

  • 在顶部,它可以不间断地移动多远
  • 在碰撞点的中心。请注意,要保持相同的速度,还需要行驶很长的距离
  • 在底部,将对象向左移动剩余距离,以便总移动距离与速度匹配
要保持速度,帧之间行驶的总距离必须保持不变。将对象定位在碰撞点可以减少移动的距离,因此可以大大降低碰撞帧期间对象的速度

正确的计算如下

 const directions = {
     LEFT: 0,
     RIGHT: 1,
 };
 const rightWallX = 100;
 const leftWallX = 0;

 if (obj.direction === directions.RIGHT) {
     obj.x = obj.x + obj.speed;
     const remainDist = (rightWallX - obj.width) - obj.x;
     if (remainDist <= 0) {
         obj.direction = directions.LEFT;
         obj.x = (rightWallX - obj.width) + remainDist;
     }
 } else if (obj.direction === directions.LEFT) {
     obj.x = obj.x - obj.speed;
     const remainDist = leftWallX - obj.x;
     if (remainDist >= 0) {
         obj.direction = directions.RIGHT;
         obj.x = leftWallX + remainDist;
     }
 }
常量方向={
左:0,,
右:1,,
};
常数rightWallX=100;
常数leftWallX=0;
如果(对象方向===方向右){
obj.x=obj.x+obj.速度;
常量remainsit=(右墙x-对象宽度)-对象x;
如果(remainst=0){
obj.direction=directions.RIGHT;
对象x=左墙x+剩余部分;
}
}

Wow!这绝对有道理!非常感谢您花时间阅读并提出您的调查方法。我