繁体   English   中英

JavaScript:当速度与时间相关时,如何计算移动精灵边界的偏移量?

[英]JavaScript: How to calculate offsets for a boundary of a moving sprite when it's speed is relative to time?

我目前遇到了一个困扰我好几天的数学难题。

我正在构建一个 JavaScript 游戏并尝试创建边界坐标来管理精灵的路径和移动,但似乎滞后/抖动/延迟对相互协调移动的不同实体造成了严重破坏。

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

这是 CodeSandbox 中问题的复制以及显示它的大部分代码: https://codesandbox.io/s/movetime-boundries-issue-example-2prow?file=/src/App.js

  var obj = { x: 10, speed: 250 };
  var obj2 = { x: 100 };

  var objHighestX = { max: 0 };

  var direction = 0;

  var canvas = document.getElementById("mainScene");
  var ctx = canvas && canvas.getContext("2d");
  ctx.imageSmoothingEnabled = false;

  ctx.font = "15px Courier";
  var render = function () {};

  var update = function (modifier) {
    // console.log("Updating");
    ctx.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight);
    ctx.fillRect(obj2.x, 60, 15, 15);
    if (obj.x > objHighestX.max) {
      objHighestX.max = obj.x;
    }
    ctx.fillText(String("X" + obj.x), 25, 100);
    ctx.fillText(String("Furthest" + objHighestX.max), 125, 100);
    if (obj.x >= obj2.x - 15) {
      direction = 1;
    } else if (obj.x <= 0) {
      direction = 0;
    }
    if (direction === 0) {
      obj.x += obj.speed * modifier;
      ctx.clearRect(obj.x - 7, 9, 17, 17);
      ctx.fillRect(obj.x, 60, 15, 15);
    }
    if (direction === 1) {
      obj.x -= obj.speed * modifier;
      ctx.clearRect(obj.x, 9, 17, 17);
      ctx.fillRect(obj.x, 60, 15, 15);
    }
  };
  var lastUpdate = Date.now();
  // The main game loop
  var main = function () {
    var now = Date.now();
    var delta = now - lastUpdate;
    lastUpdate = now;
    update(delta / 1000);
    render();
    requestAnimationFrame(main);
  };
  main();

如果有人对我的案子有任何建议或问题,我非常渴望听到。

也许我必须使用变化率来为边界创建偏移量?

我试过这样:

    if (obj.x >= obj2.x - (15 * 1 * modifier)) 

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

首先,您的增量时间计算不完整。

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() function 以反映:

 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() function 本身。 让我们看一下以下块:

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

在碰撞帧期间保持正确的速度

我注意到 object 总是在移动,这意味着给定的答案不能正确解决问题。

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

插图显示 object 移动

在此处输入图像描述

  • 在顶部,它会在不中断的情况下移动多远。
  • 在碰撞点的中心。 请注意,要保持相同的速度,仍然需要走很远的距离。
  • 在底部,object 向左移动剩余距离,使总行驶距离与速度相匹配。

为了保持速度,帧之间的总距离必须保持不变。 将 object 定位在碰撞点会减少行进距离,因此可以大大降低 object 在碰撞帧期间的速度

正确计算如下

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM