这是我在尝试使用LÖVE引擎实现游戏时遇到的问题,该引擎涵盖了带有 Lua 脚本的box2d 。
目标很简单:一个类似炮塔的物体(从顶部看,在 2D 环境中)需要确定自己的方向,使其指向目标。
炮塔在 x,y 坐标上,目标在 tx,ty 上。我们可以认为 x,y 是固定的,但 tx, ty 往往从一个瞬间到另一个瞬间变化(即它们将是鼠标光标)。
炮塔有一个转子,可以在任何给定的时刻(顺时针或逆时针)施加旋转力(扭矩)。该力的大小有一个上限,称为 maxTorque。
炮塔还具有一定的转动惯量,它对角运动的作用与质量对线性运动的作用相同。没有任何摩擦,所以如果炮塔有角速度,它会继续旋转。
炮塔有一个小的 AI 功能,可以重新评估它的方向以验证它指向正确的方向,并激活旋转器。这种情况每 dt 发生一次(每秒约 60 次)。现在看起来像这样:
function Turret:update(dt)
local x,y = self:getPositon()
local tx,ty = self:getTarget()
local maxTorque = self:getMaxTorque() -- max force of the turret rotor
local inertia = self:getInertia() -- the rotational inertia
local w = self:getAngularVelocity() -- current angular velocity of the turret
local angle = self:getAngle() -- the angle the turret is facing currently
-- the angle of the like that links the turret center with the target
local targetAngle = math.atan2(oy-y,ox-x)
local differenceAngle = _normalizeAngle(targetAngle - angle)
if(differenceAngle <= math.pi) then -- counter-clockwise is the shortest path
self:applyTorque(maxTorque)
else -- clockwise is the shortest path
self:applyTorque(-maxTorque)
end
end
... 它失败。让我用两个说明性的情况来解释:
- 炮塔围绕目标角度“振荡”。
- 如果目标“就在炮塔的后面,顺时针方向一点点”,炮塔将开始施加顺时针扭矩,并继续施加它们直到它超过目标角度的那一刻。那时它将开始在相反方向上施加扭矩。但它会获得很大的角速度,所以它会继续顺时针移动一段时间……直到目标“刚好在后面,但有点逆时针”。它会重新开始。所以炮塔会摆动甚至转圈。
我认为我的炮塔应该在达到目标角度之前开始在“最短路径的相反方向”上施加扭矩(就像停止前的汽车制动一样)。
直觉上,我认为炮塔应该“在距离目标大约一半时开始在最短路径的相反方向上施加扭矩”。我的直觉告诉我,它与角速度有关。还有一个事实是目标是移动的——我不知道我是否应该以某种方式考虑到这一点,或者只是忽略它。
我如何计算炮塔必须“开始制动”的时间?