Minecraft击退距离分析

Minecraft 击退距离的定量分析

本文旨在定量分析Minecraft中玩家被击退时的飞行距离。我们将从最简单的静止状态开始,逐步加入疾跑、连击等复杂条件,推导出通用的计算模型。

前置理论视频:BV164gMzAEkW

核心定义与符号约定

为防止歧义,首先明确本文的核心概念与数学符号:

术语 定义与说明
击退 实体从被命中瞬间开始,到其落回地面为止的整个运动过程。
击退距离 (D) 击退过程中实体在水平面产生的净位移。**方向约定:与玩家被击退时的面朝方向相同为正 (+),相反为负 (-)**。
击退初速度 (V₀) 服务器在击退开始时赋予实体的瞬时速度矢量。本文中,定义V₀的水平分量为M₀
玩家输入速度 (I) 由WASD移动输入产生的加速度。地面疾跑时 I_g ≈ 0.1274,空中时 I_a ≈ 0.02548。
阻力系数 (f) 每Tick速度衰减乘数。默认 f = 0.91。站在地面、攻击其他玩家,两者都会分别额外在 f 上乘以0.6。
Tick (t) 游戏的时间单位,1 Tick = 0.05秒。文中的时序以击退发生的瞬间为 t = 0。

静止状态下的击退

情景与数据

此情景为最简模型,用于建立分析基准:

  • 玩家状态:完全静止,无任何移动输入。
  • 击退参数:水平初速度 M0=−0.4M_0 = -0.4。
  • 过程:玩家在 0 tick 被击退作用,10 tick 回到地面。(tick = 0,10时均在地面)
  • 实验数据图:

速度计算

在无输入状态下,速度每Tick按阻力系数衰减。由于击退发生在t=0之初,且玩家起始于地面:

  • Tick 1(地面):M1=M0×fground=M0×(0.6×0.91)M_1 = M_0 × f_{ground} = M_0 × (0.6 × 0.91)
  • Tick 2-10(空中):速度递推公式为 Mt=Mt−1×fairM_t = M_{t-1} × f_{air}。

由此可推导出第 t Tick末的速度通项公式:

Mt=M0×0.6×0.91 t−1(1≤t≤9) M_t = M_0 × 0.6 × 0.91^{\,t-1} \quad (1 \le t \le 9)

位移计算与基准公式

位移在速度衰减前计算:

ΔDt=Mt−1 \Delta{D_t} = M_{t-1}

总击退距离为各Tick位移增量之和:

D静止=∑t=110ΔDt=M0+∑t=210(M0×0.6×0.91 t−2)=M0×(1+0.6∑k=080.91k)≈M0×4.470562 \begin{aligned} D_{\text{静止}} &= \sum_{t=1}^{10} \Delta D_t \\ &= M_0 + \sum_{t=2}^{10} (M_0 × 0.6 × 0.91^{\,t-2}) \\ &= M_0 × \left(1 + 0.6 \sum_{k=0}^{8} 0.91^k \right) \\ &\approx M_0 × 4.470562 \end{aligned}

代入 M0=−0.4M_0 = -0.4,得 D ≈ -1.7882248,与图中数据吻合。

此模型给出静止击退基准系数 K ≈ 4.4706:

D静止≈M0×K \boxed{D_{\text{静止}} \approx M_0 \times K}

保持疾跑状态的击退

情景

  • 玩家状态:被击退前后全程按住疾跑。
  • 击退参数:M₀ = -0.4。

速度计算

设 M₀ 为第 t Tick开始时的速度(含方向,负值代表与面朝方向相反)。其更新规律为:

  1. 加速:先加上输入速度 I(恒正)。
  2. 移动:使用加速后的速度计算位移。
  3. 衰减:最后乘以阻力系数 f,得到下一Tick初速。

即:

Mt=(Mt−1+It−1)×ft−1 M_{t} = (M_{t-1} + I_{t-1}) \times f_{t-1}
Iground=0.1274,Iair=0.02548I_{ground} = 0.1274, I_{air} = 0.02548 fground=0.6×0.91,fair=0.91f_{ground} = 0.6 \times 0.91, f_{air} = 0.91

递推后可得:

Mt=M0∏j=0t−1fj+∑k=0t−1Ik∏j=kt−1fj M_t = M_0 \prod_{j=0}^{t-1} f_j + \sum_{k=0}^{t-1} I_k \prod_{j=k}^{t-1} f_j

带入具体数值可得:

Mt=0.257631+(0.91) t−1(0.546M0−0.1880706)=0.257631−0.4064706×(0.91) t−1 \begin{align*} M_t &= 0.257631 + (0.91)^{\,t-1} \left( 0.546 M_0 - 0.1880706 \right) \\ &= 0.257631 - 0.4064706 \times (0.91)^{\,t-1} \end{align*}

位移计算与结果

第 t Tick的位移增量:

ΔDt=Mt−1+It−1 \Delta{D_t} = M_{t-1} + I_{t-1}

总击退距离:

D疾跑=∑t=110(Mt−1+It−1)=K×M0+C≈4.4703×(−0.4)+1.48≈−0.30812 \begin{aligned} D_{\text{疾跑}} &= \sum_{t=1}^{10} (M_{t-1} + I_{t-1}) \\ &= K × M_0 + C\\ &\approx 4.4703 × (-0.4) + 1.48 \\ &\approx -0.30812 \end{aligned}

疾跑状态下高频点击(20 CPS)

核心机制

每次击中其他玩家,当前水平速度会乘以 0.6, 可以当作阻力来处理。

模型修正与计算

此规则可视为对每个Tick位移增量的全局缩放。因此,在疾跑模型的基础上,总位移近似为:

D20cps≈D疾跑×0.6=(4.4703×(−0.4)+1.48)×0.6≈0.2443 \begin{aligned} D_{\text{20cps}} &\approx D_{\text{疾跑}} × 0.6 \\ &= (4.4703 × (-0.4) + 1.48) × 0.6 \\ &\approx 0.2443 \end{aligned}

一般情况

求解击退距离函数

我们考虑击退过程持续 x x 个 tick(1≤x≤10 1 \leq x \leq 10 )。第 i i 个 tick 的移动量 ΔPi\Delta P_i 定义为:

ΔPi=Mi−1+Ii−1, \Delta P_i = M_{i-1} + I_{i-1},

其中 Mi M_i 是第 i i tick 的动量,满足递推关系:

Mi=(Mi−1+Ii−1)×fi−1 M_i = (M_{i-1} + I_{i-1}) \times f_{i-1}

前 x x 个 tick 的击退距离 D(x) D(x) 为:

D(x)=∑i=1xΔPi=∑i=1x(Mi−1+Ii−1)=∑i=0x−1Mi+∑i=0x−1Ii D(x) = \sum_{i=1}^{x} \Delta P_i = \sum_{i=1}^{x} (M_{i-1} + I_{i-1}) = \sum_{i=0}^{x-1} M_i + \sum_{i=0}^{x-1} I_i

代入 Mi M_i 的通项公式:

Mi=M0∏j=0i−1fj+∑k=0i−1Ik∏j=ki−1fj M_i = M_0 \prod_{j=0}^{i-1} f_j + \sum_{k=0}^{i-1} I_k \prod_{j=k}^{i-1} f_j

得到:

D(x)=∑i=0x−1(M0∏j=0i−1fj+∑k=0i−1Ik∏j=ki−1fj)+∑i=0x−1Ii=M0∑i=0x−1∏j=0i−1fj+∑i=0x−1∑k=0i−1Ik∏j=ki−1fj+∑k=0x−1Ik \begin{aligned} D(x) &= \sum_{i=0}^{x-1} \left( M_0 \prod_{j=0}^{i-1} f_j + \sum_{k=0}^{i-1} I_k \prod_{j=k}^{i-1} f_j \right) + \sum_{i=0}^{x-1} I_i \\ &= M_0 \sum_{i=0}^{x-1} \prod_{j=0}^{i-1} f_j + \sum_{i=0}^{x-1} \sum_{k=0}^{i-1} I_k \prod_{j=k}^{i-1} f_j + \sum_{k=0}^{x-1} I_k \end{aligned}

合并含 Ik I_k 的项,交换求和顺序:

D(x)=M0∑i=0x−1∏j=0i−1fj+∑k=0x−1Ik(1+∑i=k+1x−1∏j=ki−1fj) D(x) = M_0 \sum_{i=0}^{x-1} \prod_{j=0}^{i-1} f_j + \sum_{k=0}^{x-1} I_k \left( 1 + \sum_{i=k+1}^{x-1} \prod_{j=k}^{i-1} f_j \right)

将系数写为统一形式(当 i=k i = k 时,空乘积定义为 1):

1+∑i=k+1x−1∏j=ki−1fj=∑i=kx−1∏j=ki−1fj 1 + \sum_{i=k+1}^{x-1} \prod_{j=k}^{i-1} f_j = \sum_{i=k}^{x-1} \prod_{j=k}^{i-1} f_j

因此,最终得到一般公式:

D(x)=M0∑i=0x−1∏j=0i−1fj+∑k=0x−1Ik∑i=kx−1∏j=ki−1fj \boxed{D(x) = M_0 \sum_{i=0}^{x-1} \prod_{j=0}^{i-1} f_j + \sum_{k=0}^{x-1} I_k \sum_{i=k}^{x-1} \prod_{j=k}^{i-1} f_j}

其中 1≤x≤10 1 \leq x \leq 10 ,且所有空乘积定义为 1。

观察后不难发现:

  • 距离公式是形如 D(x)=M0×A+BD(x) = M_0 \times A + B 的线性公式
    • A=∑i=0x−1∏j=0i−1fjA = \sum_{i=0}^{x-1} \prod_{j=0}^{i-1} f_j, 只与 fif_i 有关
    • B=∑k=0x−1Ik∑i=kx−1∏j=ki−1fjB = \sum_{k=0}^{x-1} I_k \sum_{i=k}^{x-1} \prod_{j=k}^{i-1} f_j, 与fi,Ikf_i, I_k有关
    • 击退距离与 M0M_0 线性相关

分析函数

一般而言,有 x=10 x = 10 ,即:

D=M0∑i=09∏j=0i−1fj+∑k=09Ik∑i=k9∏j=ki−1fj D = M_0 \sum_{i=0}^{9} \prod_{j=0}^{i-1} f_j + \sum_{k=0}^{9} I_k \sum_{i=k}^{9} \prod_{j=k}^{i-1} f_j

由于实际计算过于烦杂,这里提供Python程序求函数DD:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import math

# 计算A的值(M0的系数)
def calculateA(f):
n = 10
A = 0.0

for i in range(n):
product = 1.0
for j in range(i):
product *= f[j]
A += product

return A


# 计算B的值(常数项)
def calculateB(f, I):
n = 10
B = 0.0

for k in range(n):
B_k = 0.0
# 计算B_k = Σ_{i=k}^{9} Π_{j=k}^{i-1} f_j
for i in range(k, n):
product = 1.0
for j in range(k, i):
product *= f[j]
B_k += product
B += I[k] * B_k

return B


def main():
M0 = -0.24

# 初始化列表
f = [0.91 * 0.6 for _ in range(10)]
I = [0.02548 for _ in range(10)]

# 修改第一个元素
f[0] = 0.546 * 0.6
I[0] = 0.1274

A = calculateA(f)
B = calculateB(f, I)
D = A * M0 + B

print(f"数值公式: D = {A} × M + {B}")
print(f"代入 M = {M0} 计算:")
print(f"击退距离 D = {D}")


if __name__ == "__main__":
main()

以下,是通过脚本求得的一些距离公式参数:

tick A B D
0 4.47056 1.47996 -0.308264
1 3.08234 1.3031 0.0701655
2 2.38044 1.15909 0.20691
3 2.03085 1.03756 0.225219
4 1.86016 0.933692 0.189626
5 1.77908 0.845606 0.133974
6 1.74208 0.773022 0.0761913
7 1.72623 0.716549 0.0260559
8 1.7202 0.677326 -0.0107539
9 1.71847 0.656838 -0.0305512
  • tick = 0 时,表示玩家不攻击
  • tick = i 时候, 表示玩家前i tick进行了攻击
  • 此处的 M0=−0.4M_0 = -0.4

间隔点分析

原理分析

由于玩家的击退基本上可以分为两段

  1. Mi<0M_i < 0, 且逐渐减为0,对击退距离的贡献是负的
  2. Mi>0M_i > 0, 且逐渐增大,对击退距离的贡献是正的

要使得击退距离(DD)最大,就得使得第一阶段尽量小,第二阶段尽量大,也就是第一阶段尽量大。

间隔点就是为了实现这一目标的,只在击退后点击xx次,让前半段有点击的0.60.6阻力,后半段没有,尽量使得 DD 最大。

最佳间隔点次数

到这里,通用公式的推导过于复杂,不便于分析,在这里通过python生成一些图表,来研究不同的 M0M_0 下,最优的x选择

观察图表,发现:

  • 即使是 -1 的击退,最优的x也只有4,不到10 tick的一半,意味着其实间隔点击需要的就是尽量快,0.05s的间隔,4次点击,总时间也只有0.2s

失误情况

由于间隔点非常依赖于对刀节奏,相对于连续点击,我们很有可能,被击退作用后x个Tick,才开始间隔点,漏掉了几个tick,我们使用python脚本模拟,2,4,6,8次间隔点,在空了x个Tick后才开始间隔点,与全程连续点的击退距离差

通过上图,我们可以把情况大致分为2类:

  1. ∣M0∣>0.2|M_0| > 0.2:

    这种情况下,我们几乎没有对x(开始没打到人)的容忍度,即使是1tick没有点击到,即使是最佳的4次点击,也会使得间隔点劣于不用管对刀节奏的连续点

  2. ∣M0∣<0.2|M_0| < 0.2

    这种情况下,无论多少x为多少,点击次数多少,间隔点总是优于连续点,但是一般来说,很少有服务器的∣M0∣|M_0|会小于0.2,基本都在0.4以上(你可以利用前文的公式,直接算出服务器的M0M_0来验证


Minecraft击退距离分析
https://wtazuresky.github.io/2025/12/05/Minecraft击退距离分析/
作者
WTAzureSky
发布于
2025年12月5日
许可协议