【问题标题】:Clamp player thrust influence钳位球员推力影响
【发布时间】:2016-08-09 22:55:01
【问题描述】:

如何:限制推力的影响,同时允许其他力为无限。

示例:火箭可以沿其旋转方向推进。只有爆炸才能使它超过最高速度。我正在寻找一种理论而不是代码。

任何帮助将不胜感激。

已解决

编辑:最高速度由推力速度和摩擦力决定。

推力可以叠加到速度上,但是当摩擦力大于推力速度时可以达到最高速度。

vx = (vx + fx) *fr -- velocity = (velocity + force) *friction
vy = (vy + fy) *fr

当速度足够高时,增加的力会因摩擦而减少。

fr = .9 : 很难看到最高速度

fr = .6 : 很容易看到最高速度

【问题讨论】:

  • 请提供您的代码和更多信息,以便不详细了解love2d 的人能够更轻松地为您提供帮助。如果这在 love2d 框架中是可能的,只需将最大速度应用于自推进运动
  • 物体的速度是两个独立速度之和:“自行运动”(受某些常数限制)和“其他因素”(不受限制)。
  • object max = 50, if vel > 50 object force 如何影响velvel 会吸收force ..
  • vel = vel1 + vel2vel1 吸收 force 如果强制意味着运行。 vel2 吸收 force 如果武力意味着用人炮发射。 vel1 被锁定,vel2 没有。

标签: lua game-physics velocity love2d clamp


【解决方案1】:

使用摩擦限制加速度精确设置最大速度

前面的答案是正确的,摩擦可以限制速度,但答案错过了一些关于设置限制的细节。

首先是你的速度变量

vel = 0; //in pixels per frame. Start at 0 (or wherever you want)

你想要一个特定的最大速度(以每帧像素为单位)

maxVelocity  = 100; // set the maximum speed

并且您有一个特定的最大加速度(以每帧像素为单位)2

maxAccel = 1; // The max acceleration will occur when accelerating from 0 

你现在需要得到当速度达到 100 时停止加速所需的摩擦力。我们称之为未知摩擦力

friction = null;  // what we need to find out

你将使用方程式

vel = vel + maxAccel;  // accelerate 
vel = vel * friction;  // add friction

你知道friction 应该在加速后降低速度,这样它就不会超过maxVelocity。所以我们需要一个friction 的值,当应用于maxVelocity + maxAccel 时等于maxVelocity

maxVelocity  = (maxVelocity + maxAccel) * friction;

现在只需重新排列方程以求解未知的friction 得到

friction = maxVelocity / (maxVelocity + maxAccel);

现在您有了 friction 的值,这将确保您的速度不会超过 maxVelocity

为了稍微扩展它,您可能想要添加一个可以为您提供短期额外速度的提升,但您不希望该提升速度超过限制。您可以将friction 重新计算为新的maxVelocity,但这可能无法为您提供所需的踢球,因为速度曲线的顶端具有较低的加速度。

另一种方法是在保持相同摩擦力的同时提供额外的加速度,即计算所需的额外加速度。我们需要新的变量。

maxBoostVelocity = 120; // max boost velocity
boostAccel = null; // this will have to be calculated using the friction we have

使用与上述相同的逻辑,但根据新的最大速度和我们得到的已知摩擦重新排列摩擦解决方案

boostAccel = ((maxBoostVelocity / friction )- maxBoostVelocity);

我喜欢只使用额外的加速度来提升,所以我不必触及现有的加速度值。所以我只是从计算的提升中减去原始加速度,得到我想要的。

boostAccel = boostAccel - maxAccel;

所以在一些代码中

// the known limits
vel = 0;                 //in pixels per frame. Start at 0 (or wherever you want)
maxVelocity  = 100;      // set the maximum speed
maxAccel = 1;            // The max acceleration will occur when accelerating from 0 
maxBoostVelocity = 120;  // max boost velocity
accelerate = false;      // flag to indicate that we want to accelerate
boost = false;           // flag to indicate we want to boost
// the unknown friction and boost accel
boostAccel = null;       // this will have to be calculated using the friction we       
friction = null;         // what we need to find out
function applyAcceleration()
    if(boost){                 // is boosr flag true then add boost
        vel += boostAccel ;    // boost
    }
    if(accelerate || boost){   // is accelerate or boost flag true 
        vel += maxAccel;       // accelerate 
    }
    // always apply the friction after the accelerations 
    vel *= friction;           // apply friction
}
// in the init function calculate the friction and boost acceleration
function init(){
    friction = maxVelocity / (maxVelocity + maxAccel);
    boostAccel = ((maxBoostVelocity / friction )- maxBoostVelocity) - maxAccel;
}

【讨论】:

    【解决方案2】:

    控制:左、右和推力

    推力的最高速度可以通过摩擦来调整。

    -- VARIABLES
    player = {
        frc = .95, -- friction
        acc = .05, -- acceleration
        max = .5, -- acceleration max
        deg = 0, -- rotation in degree
        rad = 0 -- rotation in radian
        -- rotation is CW and 0 points to the right
    }
    
    -- MAIN UPDATE
    function love.update()
        control(player)
        applyVelocity(player)
    end
    
    -- UPDATE
    function control(a)
        if  L then addRotation(a,-5) end
        if  R then addRotation(a, 5) end
        if  U then thrustOn(a) else thrustOff(a) end
    end
    function applyVelocity(a)
        -- velocity + force
        a.vx = (a.vx + a.fx) *a.fr
        a.vy = (a.vy + a.fy) *a.fr
        -- position + velocity
        a.x = a.x + a.vx
        a.y = a.y + a.vy
    end
    
    -- OTHER
    function thrustOn(a)
        accelerate(a)
        rotateDist(a)
    end
    function thrustOff(a)
        a.f = 0 -- integer of force is used to convert to point (x,y) with (rad)
        a.fx = 0
        a.fy = 0
    end
    function addRotation(a,deg)
        a.deg = a.deg + deg
        a.rad = math.rad(a.deg) -- math.sin/cos functions use radian instead of degree
    end
    function accelerate(a)
        a.f = a.f + a.acc
        if a.f > a.max then a.f = a.max end
    end
    function rotateDist(a)
        -- end point of force rotated from player
        a.fx = a.f *math.sin(a.rad)
        a.fy = a.f *math.cos(a.rad)
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-03
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多