Skip to content
第18回 重力、ジャンプ、着地

3 / 4 接地中にジャンプする

このステップの目的

前の接地状態で入力を判定し、移動後の足元で接地状態を更新します。

入力を先に判定する

Player::UpdateはUpdateInput、UpdatePhysicsの順に呼びます。UpdateInputでは第17回の左右入力を残し、末尾へ次の処理を追加します。

Player.cpp(UpdateInputの末尾)cpp
if (onGround_ && input.IsPressed(Key::Jump))
{
    velocity_.y = tuning::player::JumpPower;
    remainderY_ = 0.0f;
    onGround_ = false;
    events.jumped = true;
}

JumpPowerは上向きの速度なので負の値です。IsPressedはキーを押した瞬間だけtrueを返します。入力判定より前にonGround_をfalseにすると、床に立っていてもジャンプできなくなります。

移動後に足元を調べる

UpdatePhysicsは重力を加え、横移動、縦移動を行います。その後、命中矩形を1ピクセル下へずらしたgroundProbeで床を調べます。

Player.cpp(UpdatePhysics内の足元確認)cpp
dxgame::Rect groundProbe = GetHitbox();
groundProbe.y += 1.0f;
onGround_ = stage.IsSolidAtRect(groundProbe);
if (onGround_ && velocity_.y >= 0.0f)
{
    velocity_.y = 0.0f;
    remainderY_ = 0.0f;
}

足元の確認は、移動量が0ピクセルでも行います。これにより床に立っている状態を保ち、足場から離れた後は空中へ切り替えられます。IsSolidAtRectStage.h に宣言し、Stage.cpp へ次の定義を追加します。

Stage.cppcpp
bool Stage::IsSolidAtRect(const dxgame::Rect& rect) const
{
    if (rect.width <= 0.0f || rect.height <= 0.0f)
        return false;

    const int leftTile = PixelToTile(rect.x);
    const int rightTile = PixelToTile(rect.x + rect.width - 0.001f);
    const int topTile = PixelToTile(rect.y);
    const int bottomTile = PixelToTile(rect.y + rect.height - 0.001f);

    for (int y = topTile; y <= bottomTile; y++)
    {
        for (int x = leftTile; x <= rightTile; x++)
        {
            if (IsSolidTile(x, y))
                return true;
        }
    }

    return false;
}

次のステップで UpdatePhysics() 全体とイベントへの接続を確認します。

チェックリスト
  • 床に立っているときだけ、Z キーでジャンプできる
  • キーを長押ししても、着地後に自動で再ジャンプしない
  • 床で静止しても接地状態が維持され、足場を離れると空中になる

ゲームプログラミング実践