这是我尝试使用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

... 它失败。让我用两种说明性的情况进行解释:
  • 炮塔在targetAngle周围“振荡”。
  • 如果目标“正好在炮塔后面,只是顺时针一点”,则炮塔将开始施加顺时针扭矩,并一直施加扭矩,直到其超过目标角度为止。在那一刻,它将开始在相反的方向上施加扭矩。但是它将获得可观的角速度,因此它将继续沿顺时针方向运行一段时间……直到目标“紧随其后,但略微逆时针”。它将再次开始。因此,炮塔将振荡甚至绕圆旋转。

  • 我认为,我的转塔应该在到达目标角度之前就开始在“最短路径的相反方向”上施加扭矩(例如在 parking 之前刹车)。

    凭直觉,我认为转塔应该“在距目标物镜约一半时,在最短路径的相反方向上开始施加扭矩”。我的直觉告诉我,它与角速度有关。还有一个事实是目标是可移动的-我不知道我是否应该以某种方式考虑这一点,或者只是忽略它。

    如何计算转塔何时必须“开始制动”?

    最佳答案

    倒想。当炮塔有足够的空间从当前角速度减速到死点时,该炮塔必须“开始制动”,这与从死点加速到其当前角速度所需要的房间相同

    |differenceAngle| = w^2*Inertia/2*MaxTorque.
    

    如果步长太大,目标周围的小振荡也会给您带来麻烦。这将需要更多技巧,您必须更快,更轻柔地刹车。除非您看到它,否则不必担心。

    到目前为止,这应该已经足够好了,但是还有另一个问题可能会在以后使您绊倒:决定走哪条路。如果您已经走了那么长的路,有时候走得更快。在那种情况下,您必须决定哪种方式花费的时间更少,这并不困难,但是再次,当您到达那条桥时,要越过那条桥。

    编辑:
    我的方程式是错误的,应该是Inertia/2 * maxTorque,而不是2 * maxTorque/Inertia(这就是我尝试在键盘上进行代数时得到的结果)。我已经解决了。

    试试这个:
    local torque = maxTorque;
    if(differenceAngle > math.pi) then -- clockwise is the shortest path
        torque = -torque;
    end
    if(differenceAngle < w*w*Inertia/(2*MaxTorque)) then -- brake
        torque = -torque;
    end
    self:applyTorque(torque)
    

    关于lua - 物理游戏编程box2d-使用扭矩定向类似炮塔的物体,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2617476/

    10-13 05:00