[英]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 在碰撞帧期间的速度
正确计算如下
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.