格ゲーの実装(コマンド入力とか)-多分正解編-

ずいぶん前に、格ゲーコマンド入力の実装についてエントリ書いたんだけど、滅茶苦茶嘘ついたまま放置してて、本人は時効だと思ってるなか、検索で飛んできてるひとが定期的に居るのが心苦しいので、続きを書くことにする。ホントは実際のプログラム書いてから記事にしたいのだけど、全然進まないので、仕方ないので想像で書く。ので、また嘘だったらゴメンなさいな。


前提。格ゲーのコマンド入力、レバーを下、右下、右と入れてパンチボタンを押すと「波動拳」なる特別な技が出るアレの実装。ネット上である、レバーをテンキーに見立てて、下→「2」、右下→「3」、右→「6」と表記する。例えば「波動拳」は「236P」。

先ず、プレイヤーのレバー/ボタン入力の状況を毎フレーム記録してバッファする。サイズはある程度の大きさ。少なくとも、検出したい最長のコマンド入力よりは大きい必要がある。リングバッファにすると良いだろう。テキトーに例にすると

  ...5555555544111223366P // 棒立ちから41236Pを入力。1Fの入力は人間には無理なので、多少、レバー入力が伸びている

こうなる。非効率を承知で上のような感じの文字列で処理を行う。んで、コマンド入力の検出と云うのは、いうなれば上のバッファから、コマンドのパターンマッチングをするだけだ。

例えば、上のバッファから「623P」を検出しようとする場合(入力されてないので失敗する)。実際のマッチングは、バッファをひっくり返して、近い過去から追っていく方が良さそうだ。

  P66332211144555... // バッファ
  P..3.2............ // 6が見つからないので、アンマッチ(失敗)

続いて、「41236P」(成功)の場合

  P66332211144555... // バッファ
  P6.3.2.1..4        // 全て検出したのでマッチ(成功)

後は、キャラが持っているコマンド技の数だけ、マッチング処理を繰り返せばOK。なお、「236P」と「41236P」みたく、重複している箇所のあるコマンドの扱いはどうするの?というと、コマンドに「優先順位」というのを設定しておいて、「41236P」を先に判定すればいいだけ。先にマッチした方を有効とする。

ただし、このままだと問題があるので、改良は必要だ。問題を幾つか挙げておこう。

  • 同時押し入力の扱い。バッファの方法、検出の方法
  • 溜めコマンドとかで出てくる「下要素」をどう検出するか(1or2or3にマッチする)
  • 一般的に、「コマンドの入力できる猶予フレーム」が技毎に設定されている

うん、実は正規表現とか使って、マッチングしたら一発のような気がする…。(動作速度的に好きじゃないが、多分、とるに足らない処理のハズ)

そんな感じ。