ダッシュ
ダッシュは、より速い移動とより遠くへのジャンプが可能になる、重要な仕組みである。
発動
ダッシュは、ダッシュキーを押すか、前進キーを二度押し(地面でのみ)すると発動する。
- 二度押しの場合は前進キーを離す代わりに後退キーを押しても発動できる。どちらの場合も、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
は、対象エンティティがプレイヤーの場合は基本的に無意味。