潛行
潛行是一種移動機制,可以減慢玩家的移動速度並讓他們避免從方塊上掉下來
激活方法
按下潛行鍵後會立即激活潛行,並在按下時保持激活狀態。
潛行與疾跑並不兼容。(1.14+ 除外)。
效果
當玩家在地面上時,潛行可以防止從一格及以上的高度跌落。
- 當潛行到方塊邊緣時速度會被保留,這對於特定的跳躍非常有用,如 無助跑3+1 。
- 1.11+ 中,防止掉落的最低高度改為 0.6b
- 當玩家在潛行時落在方塊邊緣時會出現「shift glitch」,在這種情況下他們可能會從方塊邊緣掉落(已在 1.16.2 中修復)。
- 在某些情況下,玩家在地面上潛行時可能會意外地掉落(範例)-- 在 1.16.2 中部分修復。
潛行時,玩家可以掛在梯子和藤蔓的一邊。
- 玩家仍然可以像往常一樣爬上去,但只要玩家留在方塊範圍內就不會掉下來。
- 一般來說,潛行使梯子跳躍更容易。
在 1.9+ 中,潛行將玩家的身高降低到 1.65m。在 1.14+ 中,潛行會進一步降低身高至 1.5m。
速度
潛行比步行慢 70%,基本加速度為 0.03,但它的應用方式與步行和疾跑不同:
- 向前潛行時,地面加速度為 0.03×0.98 = 0.0294,與預期一致。
- 當 45° 潛行時, 地面加速度為 0.0294×√2 ≈ 0.0416
代碼
它展示了潛行是如何實現的,以及為什麼它存在缺陷。
/* 位于 Entity.java,不相关的代码已被去除 */
public void moveEntity(double dX, double dY, double dZ)
{
double dX_intended = dX;
double dY_intended = dY;
double dZ_intended = dZ;
boolean sneakingOnGround = this.onGround && this.isSneaking();
if (sneakingOnGround)
{
double increment = 0.05;
//(从初始位置开始)检查 X 轴方向上玩家下方最远处的地面
while(dX != 0.0D && getCollidingBoundingBoxes(this.boundingBox.offset(dX,-1,0)).isEmpty())
{
if (dX < increment && dX >= -increment)
dX = 0.0D;
else if (dX > 0.0D)
dX -= increment;
else
dX += increment;
dX_intended = dX;
}
//(从初始位置开始)检查 Z 轴方向上玩家下方最远处的地面
while(dZ != 0.0D && getCollidingBoundingBoxes(this.boundingBox.offset(0,-1,dZ)).isEmpty())
{
if (dZ < increment && dZ >= -increment)
dZ = 0.0D;
else if (dZ > 0.0D)
dZ -= increment;
else
dZ += increment;
dZ_intended = dZ;
}
//根据先前得到的上限计算最终的 dX 与 dZ。
while(dX != 0.0D && dZ != 0.0D && getCollidingBoundingBoxes(this.boundingBox.offset(dX,-1,dZ)).isEmpty())
{
if (dX < increment && dX >= -increment)
dX = 0.0D;
else if (dX > 0.0D)
dX -= increment;
else
dX += increment;
dX_intended = dX;
if (dZ < increment && dZ >= -increment)
dZ = 0.0D;
else if (dZ > 0.0D)
dZ -= increment;
else
dZ += increment;
dZ_intended = dZ;
}
}
... //利用新得到的 dX 与 dZ 的值移动玩家(碰撞顺序:Y-X-Z)
}