Appearance
第05回 物理パラメーター調整と操作感の改善
前回: 第04回 マップデータの外部化(CSV読込) / 次回: 第06回 ステートマシン入門
前回の振り返り
CSVでマップを変更できるようにしました
- ステージの床とゴール位置をCSVから読み込みました
0、1、2の値をゲーム内の地形へ変換しました- 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);
}ジャンプ入力
地面にいるときだけ跳べる
onGroundがtrueのときだけジャンプできます- ジャンプ時は
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つ選ぶ
- 関係する値を1つだけ変える
- 同じルートをもう一度プレイする
- 変更前後の差を記録する
- 採用するか戻すか決める
変更ログの例
数値と理由を残す
- 調整は感覚だけで終わらせず、理由を短く書きます
- 変更ログがあると、後で戻す判断もしやすくなります
- 発表時の「工夫した点」にも使えます
text
変更前:
accel = 1, maxSpeed = 5, jumpPower = -14
変更後:
accel = 1, maxSpeed = 6, jumpPower = -13
理由:
横移動が少し遅く、足場間の移動が窮屈だった。
ジャンプは高すぎたため、少し低くした。よくある問題
手触りが悪くなる原因を分ける
- 動き出しが重い
accelが小さい可能性がある - 止まりにくい
frictionが小さい可能性がある - 横移動が速すぎる
maxSpeedが大きい可能性がある - ジャンプが届かない
jumpPower、gravity、足場間隔を確認する - 落下が速すぎる
maxFallSpeedを確認する
実習1: 横移動を調整する
加速、最高速度、摩擦を比較する
- 現在の値で長い平地を移動する
maxSpeedを1だけ上げて比較するfrictionを変えて止まり方を比較する- 採用した値と理由を変更ログに書く
- 変更後も床衝突が破綻していないか確認する
実習2: ジャンプを調整する
高さと落下速度を比較する
- 同じ足場からジャンプする
jumpPowerを変えて高さを比較するgravityを変えて上昇と落下のテンポを比較するmaxFallSpeedを変えて落下時の操作感を比較する- 採用した値と理由を変更ログに書く
相互プレイ
自分以外の感覚で確認する
- 1人にプレイしてもらう
- 操作しにくかった場所を聞く
- 「速い」「遅い」だけでなく、どの場面かを聞く
- 変更する場合は、値を1つだけ変える
- 変更後、同じ場所をもう一度プレイしてもらう
今日の最低到達
操作感を説明できる状態にする
- 横移動の値を1つ以上比較している
- ジャンプ関連の値を1つ以上比較している
- 変更ログが残っている
- 採用した値の理由を説明できる
- 次回、敵やギミックを追加できる程度に操作が安定している
今回のまとめ
物理パラメーターで操作感を調整しました
- 加速、最高速度、摩擦で横移動を調整しました
- ジャンプ力、重力、落下速度上限でジャンプ感を調整しました
- 同じマップで変更前後を比較しました
- 変更ログを残し、採用理由を説明できる状態にしました
- 次回は、敵やギミックを追加してゲームのルールを強めます