Sneaking/zh: Difference between revisions

From Minecraft Parkour Wiki
Content added Content deleted
(Created page with "== 速度 ==")
No edit summary
 
(21 intermediate revisions by the same user not shown)
Line 5: Line 5:




<span id="Activation"></span>
== 激活方法 ==
== 激活方法 ==


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


潜行与[[Special:MyLanguage/Sprinting|疾跑]]并不兼容。(1.14+除外)。
潜行与[[Special:MyLanguage/Sprinting|疾跑]]并不兼容。(1.14+ 除外)。






<span id="Effects"></span>
== 效果 ==
== 效果 ==


当玩家在地面上时,潜行可以防止他们跌落 1 个方块以上。
当玩家在地面上时,潜行可以防止从一格及以上的高度跌落


* 当潜行到方块边缘时速度持不变的,这对于特定的跳跃非常有用,如 [https://youtu.be/y1lWdS_aZM0 无助跑3+1] 。
* 当潜行到方块边缘时速度会被,这对于特定的跳跃非常有用,如 [https://youtu.be/y1lWdS_aZM0 无助跑3+1] 。
* 1.11+ 中,下限改为0.6b
* 1.11+ 中,防止掉落的最低高度改为 0.6b
* 当玩家在潜行时落在方块边缘时会出现“shift glitch”,在这种情况下他们可能会掉下来(已在 1.16.2 中修复)
* 当玩家在潜行时落在方块边缘时会出现“shift glitch”,在这种情况下他们可能会从方块边缘落(已在 1.16.2 中修复
* 在某些情况下,玩家在地面上潜行时可能会意外地掉下来([https://youtu.be/EqWbKIrS-FY 范例])-- 在1.16.2中部分修复。
* 在某些情况下,玩家在地面上潜行时可能会意外地掉([https://youtu.be/EqWbKIrS-FY 范例])-- 在 1.16.2 中部分修复。


潜行时,玩家可以挂在[[Special:MyLanguage/Ladders and Vines|梯子和藤蔓]]的一边。
潜行时,玩家可以挂在[[Special:MyLanguage/Ladders and Vines|梯子和藤蔓]]的一边。


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


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






<span id="Speed"></span>
== 速度 ==
== 速度 ==


潜行比步行慢 70%,基本加速度为 '''0.03''',但它的应用方式与步行和疾跑不同:
<div lang="en" dir="ltr" class="mw-content-ltr">
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:
</div>


*向前潜行时,地面加速度为 0.03×0.98 = 0.0294,与预期一致。
<div lang="en" dir="ltr" class="mw-content-ltr">
* [[Special:MyLanguage/45 Strafe|45° ]]潜行时, 地面加速度为 0.0294×'''√'''2 ≈ 0.0416
* When sneaking forward, the ground acceleration is 0.03×0.98 = 0.0294, as expected.
* When sneaking [[Special:MyLanguage/45 Strafe|diagonally]], the ground acceleration is 0.0294×'''√'''2 ≈ 0.0416
</div>






<span id="Code"></span>
<div lang="en" dir="ltr" class="mw-content-ltr">
== Code ==
== 代码 ==
</div>


它展示了潜行是如何实现的,以及为什么它存在缺陷。<syntaxhighlight lang="java">
<div lang="en" dir="ltr" class="mw-content-ltr">
/* 位于 Entity.java,不相关的代码已被去除 */
It is worth showcasing how sneaking is implemented, and why it's flawed.<syntaxhighlight lang="java">
/* In Entity.java, stripped of irrelevant code */
public void moveEntity(double dX, double dY, double dZ)
public void moveEntity(double dX, double dY, double dZ)
{
{
Line 61: Line 58:
{
{
double increment = 0.05;
double increment = 0.05;
</div>


//(从初始位置开始)检查 X 轴方向上玩家下方最远处的地面
<div lang="en" dir="ltr" class="mw-content-ltr">
//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())
while(dX != 0.0D && getCollidingBoundingBoxes(this.boundingBox.offset(dX,-1,0)).isEmpty())
{
{
Line 73: Line 68:
else
else
dX += increment;
dX += increment;
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
dX_intended = dX;
dX_intended = dX;
}
}
//(从初始位置开始)检查 Z 轴方向上玩家下方最远处的地面
//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())
while(dZ != 0.0D && getCollidingBoundingBoxes(this.boundingBox.offset(0,-1,dZ)).isEmpty())
{
{
Line 88: Line 81:
else
else
dZ += increment;
dZ += increment;
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
dZ_intended = dZ;
dZ_intended = dZ;
}
}
//根据先前得到的上限计算最终的 dX 与 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())
while(dX != 0.0D && dZ != 0.0D && getCollidingBoundingBoxes(this.boundingBox.offset(dX,-1,dZ)).isEmpty())
{
{
Line 105: Line 96:
dX += increment;
dX += increment;
dX_intended = dX;
dX_intended = dX;
</div>


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


... //利用新得到的 dX 与 dZ 的值移动玩家(碰撞顺序:Y-X-Z)
<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)
}
}
</syntaxhighlight>
</syntaxhighlight>
[[File:Sneak illustrated.png|none|thumb|600x600px|Illustration of the code presented above. The red blocks are necessary for the player to sneak on top of the green block.]]
[[File:Sneak illustrated zh.png|none|thumb|600x600px|上述代码的图示。红色方块是玩家在绿色方块上潜行所必需的。]]
</div>

Latest revision as of 04:42, 16 August 2023

Other languages:

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


激活方法

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

潜行与疾跑并不兼容。(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)
}
上述代码的图示。红色方块是玩家在绿色方块上潜行所必需的。