ゲームを知る

デモ 006先行入力

デモを読み込んでいます
上の段は先行入力なし、下の段は先行入力ありで同じ入力を自動で再生しています。点の列は中の足場に着地する前の 1 フレームごとの足元の位置です。色の付いた点のうちにジャンプを押せば、着地と同時に跳びます。下のボタンで自分でも試せます。ステージをクリックすると、キーボード(← → で移動、スペースか ↑ でジャンプ)でも操作できます。

第一章 操作感No.006

先行入力

Input Buffer別名 入力バッファ、ジャンプバッファ

概要

着地や攻撃の終わりのように、まだ次の行動に移れないうちに押されたボタンを短いあいだ覚えておき、移れるようになった瞬間に実行する仕組み。プレイヤーは着地と同時に跳んだつもりでも、実際には着地の少し前に押していることがある。先行入力がないと、押したのにジャンプしなかったと感じる。

使われる場面

足場から足場へ続けて跳び移る場面
着地したらすぐ次へ跳びたいので、着地の瞬間に合わせて押したジャンプが少し早すぎることがある。先行入力があれば、着地の少し前に押したジャンプも着地と同時に跳ぶ。
高い所から落ちて着地する場面
速く落ちているほど 1 フレームで進む距離が長く、着地の瞬間を目で合わせにくい。先行入力があれば、着地より早めに押したジャンプも跳ぶ。
攻撃や回避を続けて出す場面
攻撃の動きが終わる前に押した次の攻撃や回避を覚えておき、動きが終わった瞬間に出す。動きの終わりを待たずに押せるので、続けて出す操作がとぎれない。
メニューを素早く操作する場面
画面が切り替わる途中に押したボタンを覚えておき、切り替わった直後に実行する。切り替わりを待たずに押しても、操作を取りこぼさない。

判断基準

こういうときこうする
着地の直前にジャンプを押したのに跳ばなかった、という感想が出る先行入力を入れる。0.1 秒(毎秒 60 回の更新で 6 フレーム)から試し、0.05〜0.15 秒の幅で調整する。
空中で押したジャンプがしばらくたって着地したときに出る先行入力が長すぎる。着地の直前に押したジャンプだけが跳ぶまで短くする。
ジャンプボタンを押したまま着地すると、勝手に跳び続ける覚えるのをボタンを押し始めた瞬間だけにする。押し続けている状態を見て跳ばせると、ボタンを離すまで着地のたびに跳ぶ。
押す長さで高さが変わるジャンプ(可変ジャンプ)で、先行入力で跳んだときだけ高さが変わらない先行入力で跳んだときも、跳んだ時点でボタンを押し続けているかを見る。着地の前に離していたら、低いジャンプにする。
攻撃や回避を続けて押しても、次が出ないことがあるジャンプと同じ先行入力を攻撃や回避にも付ける。覚えるのは最後に押した一つにする。
前の画面で押したボタンが次の画面の選択肢を決めてしまう取り消せない選択の画面では先行入力を使わず、画面が切り替わった直後の押下を捨てる。

遊んでこう感じたら

  • ボタンを押したのにジャンプしなかった操作
  • 押したつもりのないタイミングでジャンプした操作
  • 攻撃を続けて押しても、次の攻撃が出ないことがある操作

指示の例

  • 着地の直前にジャンプを押しても跳ばないことがある。先行入力を入れて、着地の 0.1 秒前までに押したジャンプは着地と同時に跳ぶようにして

  • 空中でジャンプを押すと、忘れた頃に着地してから跳んでしまう。先行入力が長すぎるので、今の半分くらいに短くして

  • ジャンプボタンを押したまま着地すると、勝手に跳び続ける。先行入力は押し始めた瞬間だけを覚えるようにして、押しっぱなしでは跳ばないようにして

  • 攻撃の最中に次の攻撃を押しても出ないことがある。攻撃にも先行入力を付けて、動きが終わる 0.1 秒前くらいから押した攻撃は終わった瞬間に出るようにして

詳細

着地の前に押したジャンプが消える理由

足場から足場へ続けて跳ぶとき、プレイヤーは着地したらすぐ次へ跳ぼうとして着地の瞬間に合わせてジャンプを押す。着地の瞬間は落ちてくるキャラクターと足場の間隔を目で見て予想するしかないので、押すのが着地より少し早くなることがある。毎秒 60 回の更新なら 1 フレームは約 0.017 秒である。先行入力のないゲームでは、押すのが着地より 1 フレーム早かっただけで、その押下は空中で押したものとして捨てられる。ボタンを押したまま着地しても、押し直すまでは跳ばない。プレイヤーの目には着地と同時に押したように見えるので、ボタンが効かなかったと感じる。

そこで、次の行動に移れないあいだに押されたボタンを短いあいだ覚えておき、移れるようになった瞬間に実行する。この仕組みを先行入力と呼ぶ1。ジャンプなら、着地の少し前に押されたジャンプを覚えておき、着地と同時に跳ばせる。

覚えておく押下の数え方

ジャンプが押された瞬間に、押してからのフレーム数を 0 に戻し、その後は 1 フレームごとに 1 ずつ増やす。地面に立っていて、このフレーム数が先行入力の長さ以内なら跳ばせる。先行入力を 0 にすると、立っているときに押したジャンプしか跳ばない。

数え始めるのはボタンを押し始めた瞬間だけにする。押し続けている状態を見て跳ばせると、ボタンを押したまま着地するたびに跳び続ける。跳んだら覚えていた押下を捨て、一度の押下で二度跳ばないようにする。

let framesSincePress = Infinity; // 覚えている押下がないあいだは無限大

// 1 ステップごとに
if (jumpPressed) framesSincePress = 0; // 押し始めた瞬間だけ数え直す

if (grounded && framesSincePress <= bufferFrames) {
  velocityY = jumpSpeed;
  framesSincePress = Infinity; // 使った押下は捨てる
}
framesSincePress += 1;

長さの目安

目安は 0.05〜0.15 秒ほど(毎秒 60 回の更新で 3〜9 フレーム)である。0.1 秒(6 フレーム)前後から試し、遊びながら調整する。短すぎると、着地の少し前に押したジャンプが消える感じが残る。長すぎると、空中で押したことを忘れた頃に着地と同時に跳ぶ。たとえば、空中で思わず押したジャンプが着地の瞬間に出て、止まるつもりだった足場から跳び出してしまう。

デモでは先行入力を 6 フレームにすると、足場から体の高さほど上で押したジャンプまで跳ぶ。15 フレームにすると、跳び上がった高さの 9 割ほどの位置で押したジャンプでも着地と同時に跳ぶ。落ちる速さが速いゲームほど、着地の前の 1 フレームで進む距離が長いので、同じ先行入力でも足場から離れた位置で押したジャンプまで跳ぶ。

ジャンプ以外の行動への使い方

先行入力はキャラクターがすぐには次の行動に移れないあいだに押されたボタンなら、ジャンプ以外にも使える。攻撃の動きの途中に押した次の攻撃や、被弾でよろけているあいだに押した回避、画面の切り替わり中に押したメニューの決定などが対象になる。攻撃や回避では、動きが終わる何フレーム前から押下を覚えるかも決める。早くから覚えるほど続けて出しやすくなる一方で、押した後で止めたくなっても、覚えた行動が出てしまう。

覚えておく押下は最後に押した一つにする。押した順にすべてを覚えて出すと、連打した分だけ行動が続き、止めたいときに止まらない。

メニューや会話では、前の画面で押したボタンが次の画面の選択肢を決めてしまうことがある。売却やセーブの上書きのように取り消せない選択の画面では先行入力を使わず、画面が切り替わった直後の押下は捨てる。

コヨーテタイムとの違い

「コヨーテタイム」が受け付けるのは、足場を離れた後に遅れて押したジャンプである。先行入力は逆に、着地の前に早く押したジャンプを受け付ける。二つは受け付ける向きが逆なので、片方だけを入れても、もう片方の場面では押したのにジャンプしなかった感じが残る。

脚注

  1. 英語の input buffer の buffer はデータを一時的にためておく場所を指すプログラミングの用語で、押された入力をためておくことからこう呼ぶ。 ↩

関連項目