Skip to content
第17回 加速度、摩擦、移動の端数

2 / 4 摩擦と最高速度を加える

このステップの目的

キーを離した際に床の摩擦によって速度をゼロへ近づけて停止させ、最高速度(MaxSpeed)でクランプして速度の過剰な増加を防ぎます。

摩擦(Friction)による滑らかな減速

地上を移動するプラットフォーマーでは、キーを離した際に床との摩擦が働き、速度が落ちて停止する挙動が必要です。
摩擦は、**「現在進んでいる向きと逆の方向へ力を加える」**ことで表現します。

  • 現在右へ動いている場合(velocity_.x > 0):摩擦を減算する
  • 現在左へ動いている場合(velocity_.x < 0):摩擦を加算する
Player.cpp(無入力時の摩擦減速)cpp
    // 左右どちらのキーも押されていない場合(無入力時)
    else
    {
        if (velocity_.x > 0.0f)
        {
            // 右へ進んでいるときは減速し、0未満には下げない
            velocity_.x = std::max(0.0f, velocity_.x - tuning::player::Friction * deltaTime);
        }
        else if (velocity_.x < 0.0f)
        {
            // 左へ進んでいるときは加速し、0を超えて正にしない
            velocity_.x = std::min(0.0f, velocity_.x + tuning::player::Friction * deltaTime);
        }
    }

0を通り越して逆走する現象の防止

ここで重要なのは std::max(0.0f, ...)std::min(0.0f, ...) によるゼロでの停止処理です。
もし単純に velocity_.x -= Friction * deltaTime と計算してしまうと、速度がわずかに残った状態から摩擦を引いた際に符号が反転し、停止するはずが逆方向へ勝手に動き出してしまう不具合が発生します。減速によって0に達した時点で停止させるガードが必要です。

最高速度(MaxSpeed)による制限(Clamp)

キーを押し続けた場合、加速度によって速度は際限なく増加してしまいます。
速度が過剰に大きくなると、操作が困難になるだけでなく、第19回で扱う「壁抜け(コリジョン抜け)」の原因になります。

そのため、左右の速度が指定した最高速度(tuning::player::MaxSpeed)の範囲に収まるよう、std::clamp で制限します。

Player.cppcpp
    // 2. 速度を [-MaxSpeed, +MaxSpeed] の範囲内にクランプする
    velocity_.x = std::clamp(velocity_.x,
        -tuning::player::MaxSpeed, tuning::player::MaxSpeed);

正の方向(右)と負の方向(左)に対称な最大値を適用することで、左右どちらにも均等な最高速度が維持されます。

チェックリスト
  • キーを離した際、進行方向と逆向きに摩擦が加算・減算される仕組みを理解している
  • 摩擦による減速が0を通り越して反対向きへ逆走しないようガードされている
  • std::clamp によって、速度が MaxSpeed を超えて過剰に増加しないよう制限されている

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