マガジン

横スクロールアクションの作り方:ジャンプの気持ちよさ

遊びをつくる

執筆にClaudeを使用しています。

大きな荷物で詰まった細い道を測り、軽い部品へ置き換えて流れを整える模型。
記事のテーマをもとに制作したAI生成の写真風イメージ。

横スクロールアクションを作るとき、多くの人がまず「マップを描く」「敵を置く」「当たり判定を書く」という順番で考えます。しかし実際にプレイして「なんか重い」「操作がかみ合わない」と感じるゲームのほとんどは、ジャンプの挙動が原因です。ステージのデザインがどれほど丁寧でも、ジャンプが気持ちよくなければプレイヤーは続けません。 ジャンプの「気持ちよさ」は感覚的な話に聞こえますが、物理的なパラメータと入力への応答速度に分解できます。つまり数値を調整する作業です。この記事では、ジャンプを構成する要素を一つずつ整理し、どの数値をどう変えると何が変わるかを具体的に示します。

この記事の目次
  1. ジャンプを「重力×初速」だけで考えない
  2. 非対称重力:上昇と下降で重力を変える
  3. 可変ジャンプ:長押しで高さをコントロールする
  4. コヨーテタイムと先行入力:「入力を拾う」設計
  5. 調整の手順:数値より感触を先に決める
  6. 次の行動
  7. 参考資料

ジャンプを「重力×初速」だけで考えない

物理の教科書的なジャンプは、初速を与えてあとは重力に任せるモデルです。コードにするとこうなります。

  • ジャンプボタンを押した瞬間にY方向の速度を上向きにセット
  • フレームごとに重力加速度を加算して速度を更新
  • 速度をキャラクターの位置に反映

このモデルは正確ですが、気持ちよくはありません。理由は二つあります。一つ目は、上昇と下降が対称になること。放物線の頂点付近で動きが「ふわっ」と止まるように見え、操作の手応えが薄れます。二つ目は、ボタンを離してもジャンプの高さが変わらないこと。マリオやメトロイドなど気持ちのよいアクションゲームは、ボタンを早く離すと低く飛び、長押しすると高く飛ぶ「可変ジャンプ」を採用しています。

まず目指すべき方向は「上昇は速く、下降はさらに速く、かつボタン長押しで高さを調整できる」形です。

非対称重力:上昇と下降で重力を変える

最も効果が高い改善は、上昇中と下降中で重力の強さを変えることです。

上昇中の重力を gravityUp、下降中を gravityDown として別々に定義します。gravityDown を gravityUp の2〜3倍程度に設定すると、キャラクターが頂点に達したあと素早く落ちるようになります。これにより「ふわふわ感」が消え、着地のタイミングが読みやすくなります。

擬似コードで表すと次のようになります。

if (velocityY < 0) {
  // 上昇中
  velocityY += gravityUp * deltaTime;
} else {
  // 下降中または停止
  velocityY += gravityDown * deltaTime;
}

deltaTime はフレームごとの経過時間(秒)です。フレームレートが変動してもジャンプの挙動が安定するように、必ずこの値を掛けてください。フレームレート固定の環境でも習慣にしておくと移植時に困りません。

調整の目安として、上昇から下降に転じるまでの時間が0.3〜0.5秒、頂点から着地までが0.2〜0.35秒になるとテンポよく感じやすいです。ただしこれは参考値であり、ゲームのステージ高さや移動速度との兼ね合いで変わります。

可変ジャンプ:長押しで高さをコントロールする

可変ジャンプの実装方法はいくつかありますが、シンプルなのは「ボタンを押している間だけ上昇重力を弱める」方式です。

  1. ジャンプボタンを押した瞬間に上向きの初速を与える
  2. ボタンを押し続けている間は gravityUp を通常より小さい値(例:通常の0.4倍)にする
  3. ボタンを離した瞬間、または上昇速度が一定値を下回った瞬間に gravityUp を通常値に戻す

別の方式として「ボタンを離したとき、上向き速度が残っていれば一定値まで強制的に小さくする」方法もあります。こちらはジャンプの頂点高さがより明確に二段階(低ジャンプ・高ジャンプ)に分かれます。どちらが合うかはゲームのスタイルによります。プラットフォームを精密に踏み分けるゲームには後者、リズムやスピード重視のゲームには前者が向きやすいです。

よくある失敗は、可変ジャンプの「最低高さ」を小さくしすぎることです。最低でもキャラクターの身長の1.5〜2倍程度は飛べないと、低いブロックを越えることさえできず、プレイヤーがストレスを感じます。

コヨーテタイムと先行入力:「入力を拾う」設計

どれだけジャンプ自体を丁寧に作っても、「ジャンプしたのに反応しなかった」という体験が積み重なるとプレイヤーは操作感が悪いと感じます。これを防ぐ仕組みが二つあります。

コヨーテタイム(Coyote Time)は、足場の端を踏み外した直後もわずかな時間(0.1〜0.15秒程度)ジャンプを許可する仕組みです。名前はアニメのキャラクターが崖から踏み出した後に一瞬空中に静止する演出に由来します。地面判定が切れた瞬間にカウントダウンを開始し、その間はジャンプ可能フラグを立てたままにするだけで実装できます。この仕組みがないと、プレイヤーは「崖の端でジャンプしたのにすり抜けた」と感じます。

先行入力(Jump Buffer)は逆方向の問題を解決します。着地の少し前にジャンプボタンを押しても、着地した瞬間にジャンプが発動する仕組みです。0.1〜0.2秒程度のバッファを持ち、「直前にジャンプボタンが押された」という情報を一時保存します。着地判定が発生したとき、このバッファが残っていればそのままジャンプします。これにより、連続ジャンプのテンポが格段に良くなります。

この二つはジャンプを「気持ちよく感じさせる」技術の中でも効果対実装コストが最も高い部類です。物理パラメータを調整する前にまず入れておくことをおすすめします。

調整の手順:数値より感触を先に決める

パラメータ調整は数値から始めると迷子になります。先に「このゲームのジャンプはどんな感触にしたいか」を言葉で決めてください。

参考になる問いは次のとおりです。

  • ジャンプは重い(パワフル)か、軽い(素早い)か
  • 滞空時間は短く操作感を鋭くしたいか、長くアクロバティックにしたいか
  • 敵や障害物のパターンは素早い反射を要求するか、タイミングの読み合いか

これらが決まったら、まず初速と重力の比率だけを調整して「だいたいこのくらいの高さと速度」というベースラインを決めます。次にコヨーテタイムと先行入力を入れます。最後に可変ジャンプの幅(最低高さと最高高さの差)を詰めます。

一度に複数のパラメータを変えると何が効いたかわからなくなります。変更は一項目ずつ、プレイして確認してから次に進む習慣をつけてください。

テストプレイは自分だけで行わないほうがよいです。作った本人は無意識に操作を補正するため、ジャンプのタイミングのずれに気づきにくくなります。他の人に一度プレイしてもらい、「ジャンプでストレスを感じた場面」を口頭で教えてもらうのが最も早い改善につながります。

次の行動

まず既存のジャンプ実装にコヨーテタイムと先行入力だけを追加してプレイしてみてください。それだけで操作の「拾い」が変わり、気持ちよさの変化を実感できます。そのうえで非対称重力と可変ジャンプを段階的に加えると、調整の効果が分かりやすくなります。作ったゲームはHTMLまたはZIPファイルとしてアソバースに投稿し、実際のプレイヤーからの反応を次の調整の材料にしてみてください。

参考資料

  • Game Programming Patterns(Robert Nystrom著、Web公開版)
  • Celeste開発チームによるGDC講演資料「Designing Celeste's Coyote Time and Jump Buffering」