Sprinting/ja: Difference between revisions
Content added Content deleted
(Created page with "if (this.sprintToggleTimer > 0) { --this.sprintToggleTimer; }") |
(Created page with "空中でのダッシュの発動が1tick遅延しているのは、<code>airMovementFactor</code>の取得が空中移動の適用の際に行われるため(airMovementFactorはプレイヤーが動いた後に更新される)。<br> 対して、プレイヤーが地面にいるときは、移動前に更新が行われる<code>movementSpeed</code>から倍率が直接取得される(<code>setSprinting</code>のメソッドで修飾子が適用される)。<br>...") |
||
(14 intermediate revisions by the same user not shown) | |||
Line 9: | Line 9: | ||
* 二度押しの場合は前進キーを離す代わりに後退キーを押しても発動できる。どちらの場合も、7tick以内に前進し直す必要がある。 |
* 二度押しの場合は前進キーを離す代わりに後退キーを押しても発動できる。どちらの場合も、7tick以内に前進し直す必要がある。 |
||
* 前進キーを離すと切れる。 |
* 前進キーを離すと途切れる。 |
||
* ダッシュキーを押し続けない限り、30秒経つと切れる。 |
* ダッシュキーを押し続けない限り、30秒経つと途切れる。 |
||
* [[Special:MyLanguage/Sneaking/ja|スニーク]]中はダッシュできない(1.14以降を除く)。 |
* [[Special:MyLanguage/Sneaking/ja|スニーク]]中はダッシュできない(1.14以降を除く)。 |
||
* 壁に衝突するとその次tickに切れる。 |
* 壁に衝突するとその次tickに途切れる。 |
||
* 空中では1tick遅延する(発動/停止が1tick遅れる)。 |
* 空中では1tick遅延する(発動/停止が1tick遅れる)。 |
||
Line 22: | Line 22: | ||
==速度== |
==速度== |
||
ダッシュは歩きより30%速く、基本加速度は'''0.13'''である。地面での漸近速度は約0.286m/t。 |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Sprinting is 30% faster than walking, granting a base acceleration of '''0.13'''. The asymptotic speed on ground is ~0.286 m/t. |
|||
</div> |
|||
加えて、ダッシュ中にジャンプすると、向いている方向に'''0.2'''の加速度が付与される(strafeが入力されているかは無関係)。 |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Additionally, when the player jumps while sprinting, they accelerate by '''0.2''' towards their facing (regardless of whether the player is strafing) |
|||
</div> |
|||
* これにより、ダッシュジャンプ時は素早く加速することができるため、速度を得るもっとも良い方法になっている。 |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* Strafeを入力しながらのダッシュジャンプは正面にジャンプするよりも実際には遅く、方向もずれてしまうが、使い道は存在する。 |
|||
* This means the player accelerates quickly when sprint-jumping, making it the best way to build speed. |
|||
** [[Special:MyLanguage/Backward Momentum|Backward Momentum]]との組み合わせ時など、通常のダッシュジャンプでは速度が出過ぎてしまう場合に役立つ。 |
|||
*Sprint-jumping sideways is actually slower than forward, and goes off-track. But it does have applications: |
|||
** 振り向きが必要なジャンプにおいて、「サイドステップ」の技術内で使用される。([https://youtu.be/fo2VlHOHiwo 例]) |
|||
**Useful for [[Special:MyLanguage/Backward Momentum|Backward Momentum]], in cases where a regular sprint-jump would give too much speed. |
|||
**Used in the "Sidestep" technique for jumps that require turning. ([https://youtu.be/fo2VlHOHiwo example]) |
|||
</div> |
|||
Line 41: | Line 35: | ||
==ソースコード== |
==ソースコード== |
||
以下はダッシュがどのように発動しているかに関するコード。<syntaxhighlight lang="java"> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
The following snippets of code deal with how sprinting is activated.<syntaxhighlight lang="java"> |
|||
/* EntityPlayerSP.java */ |
/* EntityPlayerSP.java */ |
||
public void onLivingUpdate() |
public void onLivingUpdate() |
||
Line 49: | Line 42: | ||
{ |
{ |
||
--this.sprintingTicksLeft; |
--this.sprintingTicksLeft; |
||
</div> |
|||
if (this.sprintingTicksLeft == 0) |
if (this.sprintingTicksLeft == 0) |
||
Line 60: | Line 52: | ||
} |
} |
||
//1tick前のプレイヤーの動きを取得する。 |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
//Takes the player's actions from the previous tick. |
|||
boolean prevJumping = this.movementInput.jump; |
boolean prevJumping = this.movementInput.jump; |
||
boolean prevSneaking = this.movementInput.sneak; |
boolean prevSneaking = this.movementInput.sneak; |
||
Line 67: | Line 58: | ||
boolean prevMovingForward = this.movementInput.moveForward >= f; |
boolean prevMovingForward = this.movementInput.moveForward >= f; |
||
//動きの入力を更新する(moveForwardを含む - スニークしている際は0.3倍される)。 |
|||
//the movement input is updated (including moveForward - keep in mind it's multiplied by 0.3 when sneaking). |
|||
this.movementInput.updatePlayerMoveState(); |
this.movementInput.updatePlayerMoveState(); |
||
</div> |
|||
[...] |
[...] |
||
//従来の方法: プレイヤーは前tickに前方に動いていなかったが今tickでは動いている。地面にいる必要がある。 |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
//LEGACY METHOD: the player wasn't moving forward on the previous tick but is now. Must be on ground. |
|||
if (!this.isSprinting() && this.onGround && !prevSneaking && !prevMovingForward && this.movementInput.moveForward >= f && isntHungry && !this.isUsingItem() && !this.isPotionActive(Potion.blindness)) |
if (!this.isSprinting() && this.onGround && !prevSneaking && !prevMovingForward && this.movementInput.moveForward >= f && isntHungry && !this.isUsingItem() && !this.isPotionActive(Potion.blindness)) |
||
{ |
{ |
||
if (this.sprintToggleTimer <= 0 && !keyBindSprint.isKeyDown()) |
if (this.sprintToggleTimer <= 0 && !keyBindSprint.isKeyDown()) |
||
this.sprintToggleTimer = 7; // |
this.sprintToggleTimer = 7; //タイマーは7tick |
||
else |
else |
||
this.setSprinting(true); |
this.setSprinting(true); |
||
} |
} |
||
//プレイヤーが前tickに前方に動いていた場合に発動する |
|||
//Activated when the player was moving forward on the previous tick |
|||
if (!this.isSprinting() && this.movementInput.moveForward >= f && isntHungry && !this.isUsingItem() && !this.isPotionActive(Potion.blindness) && keyBindSprint.isKeyDown()) |
if (!this.isSprinting() && this.movementInput.moveForward >= f && isntHungry && !this.isUsingItem() && !this.isPotionActive(Potion.blindness) && keyBindSprint.isKeyDown()) |
||
{ |
{ |
||
this.setSprinting(true); |
this.setSprinting(true); |
||
} |
} |
||
</div> |
|||
Line 100: | Line 88: | ||
⚫ | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
⚫ | |||
public void setSprinting(boolean sprinting) |
public void setSprinting(boolean sprinting) |
||
{ |
{ |
||
this.setFlag(3, sprinting); |
this.setFlag(3, sprinting); |
||
</div> |
|||
EntityAttribute movementSpeed = this.getEntityAttribute(movementSpeed); |
EntityAttribute movementSpeed = this.getEntityAttribute(movementSpeed); |
||
Line 112: | Line 98: | ||
movementSpeed.removeModifier(sprintModifier); |
movementSpeed.removeModifier(sprintModifier); |
||
⚫ | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
⚫ | |||
⚫ | |||
⚫ | |||
</div> |
|||
this.sprintingTicksLeft = sprinting ? 600 : 0; |
this.sprintingTicksLeft = sprinting ? 600 : 0; |
||
Line 122: | Line 106: | ||
以下は、1tick内に行われる手順を簡略化したもの: |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
#ダッシュ状態を更新する。 |
|||
Here is the simplified sequence of steps performed during a tick: |
|||
#速度を計算しプレイヤーを動かす。 |
|||
#Update sprinting status |
|||
⚫ | |||
#Calculate velocity and move the player |
|||
⚫ | |||
</div> |
|||
空中でのダッシュの発動が1tick遅延しているのは、<code>airMovementFactor</code>の取得が空中移動の適用の際に行われるため(airMovementFactorはプレイヤーが動いた後に更新される)。<br> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
対して、プレイヤーが地面にいるときは、移動前に更新が行われる<code>movementSpeed</code>から倍率が直接取得される(<code>setSprinting</code>のメソッドで修飾子が適用される)。<br> |
|||
The reason air sprinting activation is delayed by one tick is because the game fetches <code>airMovementFactor</code> when applying air movement (which is updated after the player has already moved). In contrast, when the player is on ground, the game gets the multiplier directly from <code>movementSpeed</code>, which is updated before moving (applies modifier in method <code>setSprinting</code>). <code>groundMovementFactor</code> is essentially useless in the case of Player entities. |
|||
<code>groundMovementFactor</code>は、対象エンティティがプレイヤーの場合は基本的に無意味。 |
|||
</div> |
Latest revision as of 14:45, 4 July 2022
ダッシュは、より速い移動とより遠くへのジャンプが可能になる、重要な仕組みである。
発動
ダッシュは、ダッシュキーを押すか、前進キーを二度押し(地面でのみ)すると発動する。
- 二度押しの場合は前進キーを離す代わりに後退キーを押しても発動できる。どちらの場合も、7tick以内に前進し直す必要がある。
- 前進キーを離すと途切れる。
- ダッシュキーを押し続けない限り、30秒経つと途切れる。
- スニーク中はダッシュできない(1.14以降を除く)。
- 壁に衝突するとその次tickに途切れる。
- 空中では1tick遅延する(発動/停止が1tick遅れる)。
- 空腹時/アイテム使用中/暗視状態ではダッシュできない。
速度
ダッシュは歩きより30%速く、基本加速度は0.13である。地面での漸近速度は約0.286m/t。
加えて、ダッシュ中にジャンプすると、向いている方向に0.2の加速度が付与される(strafeが入力されているかは無関係)。
- これにより、ダッシュジャンプ時は素早く加速することができるため、速度を得るもっとも良い方法になっている。
- Strafeを入力しながらのダッシュジャンプは正面にジャンプするよりも実際には遅く、方向もずれてしまうが、使い道は存在する。
- Backward Momentumとの組み合わせ時など、通常のダッシュジャンプでは速度が出過ぎてしまう場合に役立つ。
- 振り向きが必要なジャンプにおいて、「サイドステップ」の技術内で使用される。(例)
ソースコード
以下はダッシュがどのように発動しているかに関するコード。
/* EntityPlayerSP.java */
public void onLivingUpdate()
{
if (this.sprintingTicksLeft > 0)
{
--this.sprintingTicksLeft;
if (this.sprintingTicksLeft == 0)
this.setSprinting(false);
}
if (this.sprintToggleTimer > 0)
{
--this.sprintToggleTimer;
}
//1tick前のプレイヤーの動きを取得する。
boolean prevJumping = this.movementInput.jump;
boolean prevSneaking = this.movementInput.sneak;
float f = 0.8F;
boolean prevMovingForward = this.movementInput.moveForward >= f;
//動きの入力を更新する(moveForwardを含む - スニークしている際は0.3倍される)。
this.movementInput.updatePlayerMoveState();
[...]
//従来の方法: プレイヤーは前tickに前方に動いていなかったが今tickでは動いている。地面にいる必要がある。
if (!this.isSprinting() && this.onGround && !prevSneaking && !prevMovingForward && this.movementInput.moveForward >= f && isntHungry && !this.isUsingItem() && !this.isPotionActive(Potion.blindness))
{
if (this.sprintToggleTimer <= 0 && !keyBindSprint.isKeyDown())
this.sprintToggleTimer = 7; //タイマーは7tick
else
this.setSprinting(true);
}
//プレイヤーが前tickに前方に動いていた場合に発動する
if (!this.isSprinting() && this.movementInput.moveForward >= f && isntHungry && !this.isUsingItem() && !this.isPotionActive(Potion.blindness) && keyBindSprint.isKeyDown())
{
this.setSprinting(true);
}
if (this.isSprinting() && (this.movementInput.moveForward < f || this.isCollidedHorizontally || !isntHungry))
{
this.setSprinting(false);
}
}
/* Entity、EntityLivingBase、EntityPlayerSPから */
public void setSprinting(boolean sprinting)
{
this.setFlag(3, sprinting);
EntityAttribute movementSpeed = this.getEntityAttribute(movementSpeed);
if (movementSpeed.getModifier(sprintModifierUUID) != null)
movementSpeed.removeModifier(sprintModifier);
if (sprinting)
movementSpeed.applyModifier(sprintModifier); //sprintModifierが倍率に0.3を加える。
this.sprintingTicksLeft = sprinting ? 600 : 0;
}
以下は、1tick内に行われる手順を簡略化したもの:
- ダッシュ状態を更新する。
- 速度を計算しプレイヤーを動かす。
- 移動速度に影響する、
groundMovementFactor
とairMovementFactor
(ダッシュ時は1.3倍)を更新する。
空中でのダッシュの発動が1tick遅延しているのは、airMovementFactor
の取得が空中移動の適用の際に行われるため(airMovementFactorはプレイヤーが動いた後に更新される)。
対して、プレイヤーが地面にいるときは、移動前に更新が行われるmovementSpeed
から倍率が直接取得される(setSprinting
のメソッドで修飾子が適用される)。
groundMovementFactor
は、対象エンティティがプレイヤーの場合は基本的に無意味。