Skip to content

第05回 物理パラメーター調整と操作感の改善

前回: 第04回 マップデータの外部化(CSV読込) / 次回: 第06回 ステートマシン入門

前回の振り返り

CSVでマップを変更できるようにしました

  • ステージの床とゴール位置をCSVから読み込みました
  • 012 の値をゲーム内の地形へ変換しました
  • CSVが読めない場合は、エラーを表示して停止するようにしました
  • スクロール表示の基本として cameraX を導入しました
  • 今回は、同じステージを使って移動とジャンプの操作感を調整します

今回の目的

操作感を数値で調整できるようにする

  • 加速、減速、最高速度を調整する
  • ジャンプ力、重力、落下速度上限を調整する
  • 変更前後の違いを説明できるようにする
  • テスト用マップで同じ条件の比較を行う

今回の授業内容

物理パラメーター調整と操作感の改善

  • 操作感を決める主な数値
  • 加速と摩擦による横移動
  • ジャンプ力、重力、落下速度上限
  • 調整用マップでの比較
  • 変更ログの書き方
  • 相互プレイによるフィードバック

手触りを作る

面白さは 数値にも宿ります

一度に変えすぎない

調整対象

最初に触る数値を決める

  • accel 横移動の加速量
  • maxSpeed 横移動の最高速度
  • friction キーを離したときの減速量
  • jumpPower ジャンプ直後の上向き速度
  • gravity 毎フレーム加わる下向き速度
  • maxFallSpeed 落下速度の上限

Game.hの物理パラメーター

定数としてまとめる

  • まずは値を1か所にまとめます
  • 調整するときは、1つずつ変更します
  • 複数の値を同時に変えると、原因を切り分けにくくなります
cpp
class Game
{
private:
    static const int accel = 1;
    static const int maxSpeed = 5;
    static const int friction = 1;
    static const int gravity = 1;
    static const int maxFallSpeed = 14;
    static const int jumpPower = -14;
};

横移動の更新

加速と摩擦で動かす

  • キーを押している間、速度を増減します
  • キーを離したら摩擦で速度を0に近づけます
  • Clamp で最高速度を超えないようにします
cpp
void Game::UpdatePlayerInput()
{
    if (CheckHitKey(KEY_INPUT_LEFT))
    {
        player.vx -= accel;
    }
    else if (CheckHitKey(KEY_INPUT_RIGHT))
    {
        player.vx += accel;
    }
    else
    {
        if (player.vx > 0) player.vx -= friction;
        else if (player.vx < 0) player.vx += friction;
    }

    player.vx = Clamp(player.vx, -maxSpeed, maxSpeed);
}

ジャンプ入力

地面にいるときだけ跳べる

  • onGroundtrue のときだけジャンプできます
  • ジャンプ時は vy にマイナス値を入れます
  • 画面では y が小さいほど上なので、上向きはマイナスです
cpp
void Game::UpdatePlayerInput()
{
    // 横移動処理の後に追加

    if (CheckHitKey(KEY_INPUT_Z) && player.onGround)
    {
        player.vy = jumpPower;
        player.onGround = false;
    }
}

重力と落下速度上限

落下が速くなりすぎないようにする

  • 毎フレーム gravity を加えて落下速度を増やします
  • maxFallSpeed で落下速度に上限をつけます
  • 上限がないと、落下が速くなりすぎて操作しにくくなります
cpp
void Game::UpdatePlayerPhysics()
{
    player.vy += gravity;
    player.vy = Clamp(player.vy, -30, maxFallSpeed);

    MoveHorizontal(player.vx);

    player.onGround = false;
    MoveVertical(player.vy);
}

1ピクセル移動の意味

速く動いても床をすり抜けにくくする

  • 速度の分だけ一気に移動すると、薄い床を通り抜けることがあります
  • 1ピクセルずつ動かし、当たった時点で戻します
  • 手触り調整で速度を上げる場合も、この処理が土台になります
cpp
void Game::MoveVertical(int move)
{
    if (move == 0) return;

    int step = (move > 0) ? 1 : -1;

    for (int i = 0; i < AbsInt(move); i++)
    {
        player.y += step;

        if (stage.IsSolidAtRect(PlayerRect()))
        {
            player.y -= step;
            if (step > 0) player.onGround = true;
            player.vy = 0;
            break;
        }
    }
}

調整用マップ

同じ条件で比較する

  • 長い平地

  • 低い段差

  • 少し離れた足場

  • ゴール直前のジャンプ

  • 落下して戻れる場所

  • マップを変えながら数値も変えると、何が原因か分かりにくくなります

調整の進め方

1項目ずつ変更する

  1. 現在の値でプレイする
  2. 気になる点を1つ選ぶ
  3. 関係する値を1つだけ変える
  4. 同じルートをもう一度プレイする
  5. 変更前後の差を記録する
  6. 採用するか戻すか決める

変更ログの例

数値と理由を残す

  • 調整は感覚だけで終わらせず、理由を短く書きます
  • 変更ログがあると、後で戻す判断もしやすくなります
  • 発表時の「工夫した点」にも使えます
text
変更前:
accel = 1, maxSpeed = 5, jumpPower = -14

変更後:
accel = 1, maxSpeed = 6, jumpPower = -13

理由:
横移動が少し遅く、足場間の移動が窮屈だった。
ジャンプは高すぎたため、少し低くした。

よくある問題

手触りが悪くなる原因を分ける

  • 動き出しが重い accel が小さい可能性がある
  • 止まりにくい friction が小さい可能性がある
  • 横移動が速すぎる maxSpeed が大きい可能性がある
  • ジャンプが届かない jumpPowergravity、足場間隔を確認する
  • 落下が速すぎる maxFallSpeed を確認する

実習1: 横移動を調整する

加速、最高速度、摩擦を比較する

  1. 現在の値で長い平地を移動する
  2. maxSpeed を1だけ上げて比較する
  3. friction を変えて止まり方を比較する
  4. 採用した値と理由を変更ログに書く
  5. 変更後も床衝突が破綻していないか確認する

実習2: ジャンプを調整する

高さと落下速度を比較する

  1. 同じ足場からジャンプする
  2. jumpPower を変えて高さを比較する
  3. gravity を変えて上昇と落下のテンポを比較する
  4. maxFallSpeed を変えて落下時の操作感を比較する
  5. 採用した値と理由を変更ログに書く

相互プレイ

自分以外の感覚で確認する

  • 1人にプレイしてもらう
  • 操作しにくかった場所を聞く
  • 「速い」「遅い」だけでなく、どの場面かを聞く
  • 変更する場合は、値を1つだけ変える
  • 変更後、同じ場所をもう一度プレイしてもらう

今日の最低到達

操作感を説明できる状態にする

  • 横移動の値を1つ以上比較している
  • ジャンプ関連の値を1つ以上比較している
  • 変更ログが残っている
  • 採用した値の理由を説明できる
  • 次回、敵やギミックを追加できる程度に操作が安定している

今回のまとめ

物理パラメーターで操作感を調整しました

  • 加速、最高速度、摩擦で横移動を調整しました
  • ジャンプ力、重力、落下速度上限でジャンプ感を調整しました
  • 同じマップで変更前後を比較しました
  • 変更ログを残し、採用理由を説明できる状態にしました
  • 次回は、敵やギミックを追加してゲームのルールを強めます

おつかれさまでした!

次回予告 第06回 敵とギミックの追加

ルールに 緊張感を加えます