[MCBE][水]TNT推进计算
账号已注销
2020年05月11日 01:01

纯代码,不涉及秃头物理,请放心食用 ( ̄▽ ̄)

首先了解一下Minecraft里实体的速度:速度是一个三维向量,每一个gt都会把在上一个gt里的速度变化量累加到旧的速度上,这样就获得了新的速度。

所以Minecraft里的速度是无法连续变化的,我们无需关注加速度(因为不存在),只要直接计算速度变化量就行了。Minecraft中实体的速度是跳跃性变化的。

void __cdecl Explosion::explode(Explosion *this)

  1. 计算爆炸中心与被推进实体的受力中心的直线距离 dist

  2. 将被推进实体宽度 * 0.5 得到实体半径 entityRadius,在 BE 里 TNT 实体的体积和 JE 一样是 0.98 * 0.98 *0.98 ,所以 TNT 的 entityRadius 是0.49

  3. 计算有效距离 = dist - entityRadius ,若得到了负数则取零

  4. 计算 dist / doubleRadius 得到 dista,其中 doubleRadius 是爆炸参数,也就是爆炸影响的半径。在 BE 里 TNT 的默认爆炸半径和 JE 一样是8

  5. 当 dista ≤ 1.0时 ,说明这个实体距离爆炸中心足够近,并继续计算这次爆炸的强度 pow = (1.0 - dista) * seenPercent , 也就是这次爆炸产生的速度变化量。其中seenPercent是爆炸接触率,计算方式比较麻烦就不解释了,源码如下:

BlockSource::getSeenPercent(BlockSource *this, const Vec3 *center, const AABB *bb)

总结一下,pow = (1.0 -  (length - entityRadius) / doubleRadius) * seenPercen

然后我们就发现了一个很奇怪的东西:有效距离 = dist - entityRadius

可以猜测 mojang 这么写的原因是:他们把爆炸的距离,定义成爆炸中心到被推进实体的表面的距离,然后又偷懒了,就写成了这样奇怪的形式

在很久以前,就有人发现 BE 里 TNT 对 TNT 在 8.02 的距离上依然有效,其实所对应解释的就是这个奇怪的算法。按照这个算法,不难得出 BE 里 TNT 对 TNT 可以产生推进作用的最大有效距离是 8 + 0.5 * 0.98 = 8.49 ,而不是通常所认识的 8

加了这个奇怪的算法后,影响也不仅仅是最大的作用距离的问题这么简单。做出爆炸强度和距离的关系图像,你会发现它不是一条直线而是一条折线。这可能使得推进的计算更为复杂,也可能衍生出一些过去难以实现的新技术?一切无从得知。

爆炸强度和距离的关系图像