矢量,以最大速度计算运动力

Jon*_*ahl 7 javascript math vector game-physics

我正在建立一个小型太空射击游戏.当它涉及空间物理时,我有一个数学问题.

用文字描述这一点如下:有一个最大速度.因此,如果你全速前进,你就会像在旧的小行星游戏中一样,一遍又一遍地在屏幕上移动.如果然后释放火箭助推器,你应该继续以该速度在屏幕上移动.

然后是我现在卡住的棘手部分.

如果您将船舶任意角度旋转并再次提升,那么船舶应该尝试朝这个方向前进,并且在它移动速度方面永远不会超过最大速度.所以我的问题是.对于这个问题,谁都有一个好主意公式?如果你知道要找什么,感觉就像以前一样.:)

我添加这个小图片来说明一些矢量计算尝试做什么. 最大速度移动力

红环:最大速度

绿线:当前船舶方向.

黑线:方向(s)以及船舶在x和y中移动的速度.

黑环:运动的起源.

可以说明一下,但很难找到一个好的数学解决方案.:)

编辑

这是我现在在每一帧中使用的代码.它为船舶提供了运动,但没有给出用户必须与其火箭助推器反作用以使船停止或减速的运动力.有了它,它会立即停止释放船的加速速度.

    //Calculates ship movement rules
var shipVelocityVec = GetVectorPosByAngle(shipMoveSpeed, shipRotationAngle);
var shipUnitVec =$V([Math.cos(shipRotationAngle),Math.sin(shipRotationAngle),0]);
var rawAccel = shipAccelSpeed / shipMass;
var scale = (shipUnitVec.dot(shipVelocityVec))/(shipTopSpeed * shipTopSpeed);
var v1 = shipUnitVec.subtract(shipVelocityVec.multiply(scale));
var finalAccelVec = v1.multiply(rawAccel);
console.log(finalAccelVec);

//move ship according to rules
var shipPosVector = $V([shipxPos, shipyPos, 0]);
var movementVector =  shipPosVector.add(finalAccelVec);
shipxPos = movementVector.elements[0];
shipyPos = movementVector.elements[1];
Run Code Online (Sandbox Code Playgroud)

为了提供加速度,用户必须按住按钮.用户释放按钮的实例,加速度设置为零,并且必须再次加速以提供最大加速度油门.

找到解决方案 在这里发布它是如何完成的.

com*_*orm 1

@BlueRaja 的解决方案应该有效,尽管当您达到最大速度时,您的行为会突然改变。

如果您想要一个没有“接缝”的解决方案,我相信您可以通过对加速度添加正确的调整来实现您想要的目标,如下所示:

ship_unit_vec = [cos(ship_angle), sin(ship_angle)]
raw_accel = (engine_thrust / ship_mass)

scale = dot_product(ship_unit_vec, ship_velocity_vec) / max_speed^2

final_accel_vec = raw_accel * (ship_unit_vec - scale * ship_velocity_vec)
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 如果|ship_velocity_vec|<<max_speed,则scale * ship_velocity_vec分量可以忽略不计。
  • 如果|ship_velocity_vec|==max_speed,则scale * ship_velocity_vec组件取消“错误”方向上的所有附加加速度,并辅助“正确”方向上的加速。
  • 我从来没有尝试过,所以我不知道玩家会感觉如何......

更一般地,如果有更多的加速度源而不仅仅是船舶推进器,您可以将它们全部加在一起(例如raw_accel_vec),并一次执行上述操作:

scale_forall = dot_product(raw_accel_vec, ship_velocity_vec) / max_speed^2
final_accel_vec = raw_accel_vec - scale_forall * ship_velocity_vec
Run Code Online (Sandbox Code Playgroud)