我实现了以下功能:
function moveTowards(start, target, speed) {
if (Math.abs(target.x - start.x) < config.COLLISION_RADIUS
&& Math.abs(target.y - start.y) < config.COLLISION_RADIUS) {
return target
}
const newX = target.x - start.x
const newY = target.y - start.y
const angle = Math.atan2(newY, newX)
const x = speed * Math.cos(angle)
const y = speed * Math.sin(angle)
return {
x: start.x + x,
y: start.y + y
}
}
预计会在游戏更新循环中调用,并返回缓慢移向目标位置的位置。
它工作正常但是当我设置一个大于1的速度时,该功能永远不会实际达到目标位置,而是返回目标周围区域的位置。
我从这里算了数学:https://stackoverflow.com/a/20762210/5547718
那里的解决方案不包含速度参数,而是包含#34;幅度&#34;。
如何在没有到达目标的情况下实现变速?
(我尝试接受的值是&#34;足够接近&#34;但速度越大,我必须容忍的差异越大,实际上并没有成功)
答案 0 :(得分:2)
您的代码每帧都会进行大量不必要的计算。例如,您应该只进行以下计算:
const angle = Math.atan2(newY, newX);
const x = speed * Math.cos(angle);
const y = speed * Math.sin(angle);
在移动开始时完成一次,而不是每一帧(角度deosn在帧之间改变)。
然而,每个帧可以检查的是检查从开始到目标的距离是否小于预计的速度距离,在这种情况下只需将对象放在目标位置。
if (newX <= x && newY <= y) {
return target;
}
答案 1 :(得分:0)
使用@ Balazs和@ Michael的建议我做了以下工作并且完美地完成了:
function moveTowards(start, target, speed) {
const newX = target.x - start.x
const newY = target.y - start.y
const angle = Math.atan2(newY, newX)
const x = speed * Math.cos(angle)
const y = speed * Math.sin(angle)
if (newX*newX <= x*x && newY*newY <= y*y)
return target
return {
x: start.x + x,
y: start.y + y
}
}