Appearance
第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ピクセルでも行います。これにより床に立っている状態を保ち、足場から離れた後は空中へ切り替えられます。IsSolidAtRect も Stage.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 キーでジャンプできる
- キーを長押ししても、着地後に自動で再ジャンプしない
- 床で静止しても接地状態が維持され、足場を離れると空中になる