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

1 / 4 位置の変化を速度として持つ

このステップの目的

位置を直接書き換える実装から、毎フレームの速度(velocity_)を状態として保持し、キー入力に応じて加速度を加算する物理モデルへと移行します。

速度を内部状態として保持する理由

第14回では、キーが押されている間、位置に対して直接 position_.x += direction * MoveSpeed * deltaTime を加算していました。
この方式では、キーを押した瞬間に最高速度に達し、キーを離した瞬間に停止するため、動きが硬くなります。

滑らかな加減速を表現するためには、「現在どの速さと向きで動いているか」を表す**速度(velocity_)**をプレイヤーのメンバ変数として記憶し、キー入力によってその速度を徐々に変化させる必要があります。

Player.hcpp
namespace dxgame::platformer
{
    class Player
    {
    private:
        Vector2 position_ = {};
        Vector2 velocity_ = {}; // 現在の移動速度(ピクセル/秒)
    };
}

速度はゲームの調整値ではなく、毎フレーム刻々と変化する「プレイヤーの動的な状態」です。リトライ時やゲーム開始時には、位置とともに { 0.0f, 0.0f } へリセットします。

加速度(Acceleration)の積分

キー入力に応じて速度を変化させる計算は、等加速度直線運動に基づきます。

$$v = v_0 + a \Delta t$$

  • $v_0$ : 前フレームの速度(現在の velocity_.x
  • $a$ : 加速度(tuning::player::Acceleration
  • $\Delta t$ : 経過時間(deltaTime
Player.cppcpp
void Player::Update(const Input& input, float deltaTime)
{
    const bool moveLeft = input.IsHeld(Key::Left);
    const bool moveRight = input.IsHeld(Key::Right);

    if (moveLeft && !moveRight)
    {
        velocity_.x -= tuning::player::Acceleration * deltaTime;
    }
    else if (moveRight && !moveLeft)
    {
        velocity_.x += tuning::player::Acceleration * deltaTime;
    }
    else if (velocity_.x > 0.0f)
    {
        velocity_.x = std::max(0.0f,
            velocity_.x - tuning::player::Friction * deltaTime);
    }
    else if (velocity_.x < 0.0f)
    {
        velocity_.x = std::min(0.0f,
            velocity_.x + tuning::player::Friction * deltaTime);
    }

    velocity_.x = std::clamp(velocity_.x,
        -tuning::player::MaxSpeed, tuning::player::MaxSpeed);

    remainderX_ += velocity_.x * deltaTime;
    const int pixelMove = static_cast<int>(remainderX_);
    remainderX_ -= static_cast<float>(pixelMove);
    position_.x += static_cast<float>(pixelMove);
}

例えば、加速度が 1260.0f ピクセル/秒² である場合、右キーを1秒間押し続けると、速度は理論上 1260 ピクセル/秒 増加します。
1フレーム(約0.0167秒)ごとに加算される速度は $1260 \times 0.0167 \approx 21$ ピクセル/秒 となり、プレイヤーは徐々に速度を増していきます。

チェックリスト
  • 位置を直接書き換えるのではなく、速度 velocity_ を保持する理由を説明できる
  • 加速度 $\times \Delta t$ によって速度が毎フレーム徐々に増加する仕組みを理解している
  • 左右のキー入力に応じて速度の正負が正しく変化していることを確認できる

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