潜行

    From Minecraft Parkour Wiki
    This page is a translated version of the page Sneaking and the translation is 100% complete.
    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。


    速度

    潜行比步行慢 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)
    }
    
    上述代码的图示。红色方块是玩家在绿色方块上潜行所必需的。