潜行

From Minecraft Parkour Wiki
Revision as of 07:21, 23 June 2022 by Pjx1314 (talk | contribs) (Created page with "dX_intended = dX; } //check for furthest ground under player in the Z axis (from initial position) 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;")
Other languages:

潜行是一种移动机制,可以减慢玩家的移动速度并让他们避免从方块上掉下来


激活方法

按下潜行键后会立即激活潜行,并在按下时保持激活状态。

潜行与疾跑并不兼容。(1.14+除外)。


效果

当玩家在地面上时,潜行可以防止他们跌落 1 个方块以上。

  • 当潜行到方块边缘时,速度是保持不变的,这对于特定的跳跃非常有用,如 无助跑3+1
  • 1.11+ 中,下限改为0.6b
  • 当玩家在潜行时落在方块边缘时会出现“shift glitch”,在这种情况下他们可能会掉下来(已在 1.16.2 中修复)。
  • 在某些情况下,玩家在地面上潜行时可能会意外地掉下来(范例)-- 在1.16.2中部分修复。

潜行时,玩家可以挂在梯子和藤蔓的一边。

  • 玩家仍然可以像往常一样爬上去,但只要玩家留在方块范围内就不能掉下来。
  • 一般来说,潜行使梯子跳跃更容易。

在 1.9+ 中,潜行将玩家的身高降低到 1.65m。在 1.14+ 中,潜行会进一步降低它,降至 1.5m。


速度

Sneaking is 70% slower than walking, granting a base acceleration of 0.03, but it doesn't get applied the same way as walking and sprinting:

  • 向前潜行时,地面加速度为 0.03×0.98 = 0.0294,与预期一致。
  • 45 度潜行时, 地面加速度为 0.0294×2 ≈ 0.0416


代码

它展示了潜行是如何实现的,以及为什么它存在缺陷。

/* In Entity.java, stripped of irrelevant code */
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;

        //check for furthest ground under player in the X axis (from initial position)
        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;
        }
                
        //check for furthest ground under player in the Z axis (from initial position)
        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;

            <div lang="en" dir="ltr" class="mw-content-ltr">
dZ_intended = dZ;
        }
                
                
        //calculate definitive dX and dZ based on the previous limits.
        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;
</div>

                    
            <div lang="en" dir="ltr" class="mw-content-ltr">
if (dZ < increment && dZ >= -increment)
                dZ = 0.0D;
            else if (dZ > 0.0D)
                dZ -= increment;
            else
                dZ += increment;
            dZ_intended = dZ;
        }
    }
</div>

    <div lang="en" dir="ltr" class="mw-content-ltr">
... //move the player with the new values of dX and dZ (order of collisions: Y-X-Z)
}
Illustration of the code presented above. The red blocks are necessary for the player to sneak on top of the green block.