格ゲーの実装(コマンド入力とか)-多分正解編-
ずいぶん前に、格ゲーコマンド入力の実装についてエントリ書いたんだけど、滅茶苦茶嘘ついたまま放置してて、本人は時効だと思ってるなか、検索で飛んできてるひとが定期的に居るのが心苦しいので、続きを書くことにする。ホントは実際のプログラム書いてから記事にしたいのだけど、全然進まないので、仕方ないので想像で書く。ので、また嘘だったらゴメンなさいな。
前提。格ゲーのコマンド入力、レバーを下、右下、右と入れてパンチボタンを押すと「波動拳」なる特別な技が出るアレの実装。ネット上である、レバーをテンキーに見立てて、下→「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にマッチする)
- 一般的に、「コマンドの入力できる猶予フレーム」が技毎に設定されている
うん、実は正規表現とか使って、マッチングしたら一発のような気がする…。(動作速度的に好きじゃないが、多分、とるに足らない処理のハズ)
そんな感じ。