45° 斜跑

    From Minecraft Parkour Wiki
    This page is a translated version of the page 45 Strafe and the translation is 100% complete.
    Other languages:

    45° 斜跑是一种能比常规运动获取更多速度的技巧。

    可以通过斜跑的同时转向 45° 来实现(与其名相符)。


    下列两种方式均可实现 45° 斜跑:

    • 向左转 45° 并向右斜跑。
    • 向右转 45° 并向左斜跑。


    转向必须迅速(小于 1 刻)且精确(至少需要 ±11.5°,越接近 ±0° 加速越多),因此难以稳定使用。

    一些跳跃必须使用 45° 斜跑来通过,比如 1bm 4.375b。



    对运动的影响

    在每一刻中,玩家基于按键输入及其它因素来获取加速度。

    • 当向前移动(不使用斜跑)时,获得的加速度为
    • 当斜跑时,获得的加速度为 倍。

    因此,45° 斜跑比正常移动要快 倍(约 2%)。


    特殊情况:45° 潜行

    • 当向前潜行(不使用斜跑)时,获得的加速度为
    • 当潜行的同时斜跑时,获得的加速度为 (≈1.386)倍

    45° 潜行常用于无助跑跳跃(范例)。

    除了跑酷之外,这个技巧也尤其常见于搭路,因为这比通常潜行的速度快了约 41%。



    解释

    如下是水平运动源代码的简化版。

    /* 
     * 代码来源于 Entity 和 EntityLivingBase
     * 不必要与不相关的代码已被删去
     */
    
    public void onLivingUpdate()
    {
        /* 
         * moveStrafing 与 moveForward 表示的是相对运动。
         * 向左移动时 moveStrafing = 1.0,向右移动时 moveStrafing = -1.0,除此之外则为 0.0。
         * 向前移动时 moveForward = 1.0,向后移动时 moveForward = -1.0,除此之外则为 0.0。
         *
         * 此外,玩家潜行时 moveStrafing 和 moveForward *= 0.3。
         */
    
        this.moveStrafing *= 0.98F;
        this.moveForward *= 0.98F;
        this.moveEntityWithHeading(this.moveStrafing, this.moveForward);
    }
    
    
    
    public void moveEntityWithHeading(float strafe, float forward)
    {
        /* 模拟惯性,决定玩家有多少速度被保留到下一刻 */
        float mult = 0.91F;
        if (this.onGround)
        {
            /* 获取玩家下方 1 格方块的滑度 */
            mult *= getBlockSlipperinessAt(this.posX, this.getEntityBoundingBox().minY - 1, this.posZ);
        }
    
        /* acceleration = (0.6*0.91)^3 / (slipperiness*0.91)^3) */
        float acceleration = 0.16277136F / (mult * mult * mult);
    
        float movementFactor;
        if (this.onGround)
            movementFactor = this.landMovementFactor * acceleration;
            /* landMovementFactor 基础情况下为 0.1,疾跑时×1.3,受药水效果影响。 */
    
        else
            movementFactor = this.airMovementFactor; 
            /* airMovementFactor 基础情况下为 0.02,疾跑时×1.3 */
    
        this.updateMotionXZ(strafe, forward, movementFactor); 
        this.moveEntity(this.motionX, this.motionY, this.motionZ);
    
        this.motionY -= 0.08D; /* 重力 */
        this.motionY *= 0.98D; /* 阻力 */
    
        this.motionX *= mult;
        this.motionZ *= mult;
    }
    
    
    
    public void updateMotionXZ(float strafe, float forward, float movementFactor)
    {
        /*
         * 该函数导致了 45° 斜跑的存在。几何学在这里没有任何意义……
         * 注意:
         *     - 疾跑的乘数位于 movementFactor 中
         *     - 潜行的乘数位于 strafe 和 forward 中
         * 这可能是因为潜行在疾跑之前执行
         */
        float distance = strafe * strafe + forward * forward;
    
        if (distance >= 1.0E-4F)
        {
            distance = MathHelper.sqrt_float(distance);
                
            if (distance < 1.0F)
                distance = 1.0F;
    
            distance = movementFactor / distance;
            strafe = strafe * distance;
            forward = forward * distance;
            float sinYaw = MathHelper.sin(this.rotationYaw * Math.PI / 180.0F);
            float cosYaw = MathHelper.cos(this.rotationYaw * Math.PI / 180.0F);
            this.motionX += strafe * cosYaw - forward * sinYaw;
            this.motionZ += forward * cosYaw + strafe * sinYaw;
        }
    }