关于 Minecraft 中玩家常态最大移动速度的求解

kaatenn 发布于 15 天前 39 次阅读


先给出结论,常态下玩家的最大移动速度是 $4.317 m/s$,该结论在 MCWiki 上已有记载,本文主要是对其结论进行证明。

特别鸣谢:水晶 在证明过程中给出的支持。

MC 环境

本文参考 forge 1.20.1 版本提供的代码,使用的反混淆为 parchment 反混淆。

证明

定义摩擦系数 $f$ 和移动速度常量 $M$,其中移动速度常量在代码中由 $MOVEMENT\_SPEED$ 常量定义,为三维向量。

根据 LivingEntity#travel 中:

this.setDeltaMovement(vec35.x * (double)f3, d2 * (double)0.98F, vec35.z * (double)f3);

得到玩家得到移动指令时获取瞬时速度,为方便证明,不妨令方向为 $z$ 轴正方向,即 $M_{in} = (0, 0, |M| * 0.98)^T$。

而此时根据 LivingEntity#getFrictionInfluencedSpeed 代码:

private float getFrictionInfluencedSpeed(float pFriction) {
      return this.onGround() ? this.getSpeed() * (0.21600002F / (pFriction * pFriction *pFriction)) : this.getFlyingSpeed();
}

此时,修正后的速度为: $$M_{fix} = \frac{0.216M'}{f^3}$$
而上一刻的速度(记为 $v_l$)则会经过衰减给到当前刻,根据 LivingEntity#travel 的代码:

float f3 = this.onGround() ? f2 * 0.91F : 0.91F;

加上当前刻提供的瞬时加速度可以得知,当前的移动速度为:

$$v_c=0.91fv_l+\frac{0.216M'}{f^3}$$
在常态下,必然有 $v_l=v_c$,代入得:
$$
v = \frac{0.216M'}{(1-0.91f)f^3}=\frac{0.21168M}{(1-0.91f)f^3}
$$
通过 debug 得知将 $M=0.1, f=0.6$, 代入得 $v=4.317$。

而由 Entity#getInputVector 代码:

private static Vec3 getInputVector(Vec3 pRelative, float pMotionScaler, float pFacing) {
      double d0 = pRelative.lengthSqr();
      if (d0 < 1.0E-7D) {
         return Vec3.ZERO;
      } else {
         Vec3 vec3 = (d0 > 1.0D ? pRelative.normalize() : pRelative).scale((double)pMotionScaler);
         float f = Mth.sin(pFacing * ((float)Math.PI / 180F));
         float f1 = Mth.cos(pFacing * ((float)Math.PI / 180F));
         return new Vec3(vec3.x * (double)f1 - vec3.z * (double)f, vec3.y, vec3.z * (double)f1 + vec3.x * (double)f);
      }
}

可提取出正交变换:

$$
\begin{bmatrix}
x &
y &
z
\end{bmatrix}
\begin{bmatrix}
\sin{f} &0 &\cos{f} \\
0 &1 &0\\
-\cos{f} &0 &\sin{f}
\end{bmatrix}
$$

根据正交变换不改变模长的性质,可知稳态速度即使更换方向依然不变。

综上,玩家最大速度为 $v=4.317$。

此作者没有提供个人介绍
最后更新于 2025-01-20