Skip to content
第20回 アニメーションと音声イベント

2 / 4 物理状態に基づくアニメーション制御

このステップの目的

プレイヤーの物理状態(接地フラグおよび速度ベクトル)に基づいて、待機・走行・上昇・落下の4状態を優先順位に従って判定し、適切なアニメーションコマを進行させる制御を実装します。

状態判定の優先順位の整理

キャラクターのアニメーションは、現在の物理的な運動状態を視覚的に伝えるフィードバックです。複数の条件が同時に成り立つ可能性があるため、判定の優先順位を明確に定義します。

  1. 空中状態の判定(最優先):
    接地フラグがオフ(!onGround_)である場合、プレイヤーは空中にいます。水平移動入力があっても空中走行のアニメーションにならないよう、垂直速度(velocity_.y)を基準に判定します。
    • velocity_.y < 0.0f:上昇中(ジャンプ姿勢)
    • velocity_.y >= 0.0f:下降中(落下姿勢)
  2. 地上状態の判定:
    接地している場合のみ、水平速度の大きさ(std::abs(velocity_.x))を検査します。
    • 速度が閾値(デッドゾーン 0.1f)を超える場合:走行
    • 速度が閾値以下の場合:待機
Player.cppcpp
PlayerAnimation nextAnimation = PlayerAnimation::Idle;
if (!onGround_)
{
    nextAnimation = velocity_.y < 0.0f
        ? PlayerAnimation::Jump
        : PlayerAnimation::Fall;
}
else if (std::abs(velocity_.x) > 0.1f)
{
    nextAnimation = PlayerAnimation::Run;
}
else
{
    nextAnimation = PlayerAnimation::Idle;
}

アニメーション切り替え時のタイマーリセット

アニメーション状態が別の状態へと遷移した瞬間には、コマ送り用のタイマーとフレーム番号を先頭(0)へリセットします。

Player.cppcpp
if (nextAnimation != animation_)
{
    animation_ = nextAnimation;
    animationFrame_ = 0;
    animationTimer_ = 0;
}

タイマーをリセットする理由

タイマーをリセットせずに引き継ぐと、走行アニメーションの終了直前にジャンプへ移行した際、次の瞬間に予期せぬコマ送りが発生したり、着地した瞬間に走行の途中の足の形から再開してしまいます。
状態が切り替わった瞬間に先頭フレームから再生することで、操作に対する視覚的応答の一貫性を保ちます。

コマ送り制御とスプライトシート番号へのマッピング

アニメーションの進行は、状態ごとに設定された表示時間(frameDuration)とコマ数(frameCount)に基づいて制御します。

Player.cppcpp
animationTimer_++;
if (animationTimer_ >= frameDuration)
{
    animationTimer_ = 0;
    animationFrame_ = (animationFrame_ + 1) % frameCount;
}

描画を行う際には、GetAnimationFrame() が現在のアニメーション状態とフレーム番号をスプライトシート上の絶対フレーム番号(0〜7)へ変換します。

Player.cppcpp
int Player::GetAnimationFrame() const
{
    switch (animation_)
    {
    case PlayerAnimation::Idle:
        return animationFrame_;
    case PlayerAnimation::Run:
        return 2 + animationFrame_;
    case PlayerAnimation::Jump:
        return 6;
    case PlayerAnimation::Fall:
        return 7;
    }

    return 0;
}

描画処理(Player::Draw)はこのマッピング関数を呼び出すことで、スプライトシート内のコマ配置に依存せずに描画できます。

チェックリスト
  • 空中(上昇・落下)と地上(走行・待機)の優先順位に従ってアニメーション状態を判定できる
  • 状態遷移時にタイマーとフレーム番号を0へリセットし、不自然なコマ飛びを防ぐ理由を説明できる
  • PlayerAnimation とローカルフレーム番号からスプライトシート上の絶対フレーム番号を導出できる

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