メイドイン俺:リズムゲー解説:「楽譜」編

=前置き=

ということで、予定より遅れたものの「メイドイン俺でリズムゲーを作る際の情報共有:楽譜」について。

=考え方=

例えば「ドンドンドドドンというリズムでタッチして欲しい」というゲームを作る場合。
必要なのは「ドン」の少し前からタッチされるのを待ち、全てちゃんとタッチされたかを判定する処理。
直接時間で指定する方法などもあるものの、それだと「8種類の中からランダムにリズムを選ぶこと」や「後からリズムを簡単に変更すること」ができず、何より見てわかりにくい。
そこで、

■□■□■■■□

という画像(■は黒、□は透明のマス)を

ドンドンドドドン

というリズムとして考える。
このリズムでフラグがオンになったりする"ぶったい"を作れば色々と応用が利き、調整もやりやすい。


ということで、そういう画像からリズムを抽出する方法について解説。

=サンプル=

以前に載せたけど再掲。


以下のフレンドコードのあずかりやに2つのサンプルが置いてある。(2009/07/02現在)

  • 名前
    • カラス
  • コード
    • 3953 3745 9756


どちらも「がくふ」という"ぶったい"を使ってリズムを制御するリズムゲーになっている。


以下の解説がわからなくても、「がくふ」のマスをいじることでリズムを変更して遊ぶくらいは可能。

=実現方法=

必要な"ぶったい"は以下の4つ。

  • 楽譜
    • 前述の画像を複数列まとめたもの
  • サイクル
    • 一定周期でスイッチがオンになるもの
  • Iterイテレータ
    • 楽譜の上を1マスずつ動くもの
    • これが「楽譜のリズムでスイッチがオンになるもの」になる
  • Next(イテレータの移動先)
    • Iterを1マスずつ動かすためのもの

以下、詳細。

=楽譜=

「楽譜」は、前述の画像(リズム)をまとめたもので、例えば

ドンドンドンドン
ドンドンドドドン
ドドドンドンドン
ドドドンドドドン
ドンドドドンドン
ドドドドドンドン
ドンドドドドドン
ドドドドドドドン

という8つのリズムをまとめて

■□■□■□■□
■□■□■■■□
■■■□■□■□
■■■□■■■□
■□■■■□■□
■■■■■□■□
■□■■■■■□
■■■■■■■□

という画像にしたもの。


この画像の移動するラインを変更することでリズムを変更したり、アニメを切り替えることでさらに複数のリズムを扱うことが可能になる。


マスの大きさは1マスでもいいが、0.5マスまでなら製作コストもたいして違わず、縦横2倍=4倍の情報量を持てるので、0.5マスの方がオススメ。


この解説では、「楽譜」は「画像だけの"ぶったい"」なので他の処理は特に必要ないが、場合によっては「IterとぶつかったらSEを鳴らす」などの処理を仕込むことも可能。

=サイクル=

「サイクル」は「一定周期でスイッチがオンになる"ぶったい"」で、以前に少しだけ書いたもの。サンプルの2つのゲームでは「リズム」という名前の"ぶったい"になっているが、ここでは説明のために「サイクル」という名前にしておく。


具体的には、「"速度:はやい"で5.5マス先に"ごっつんこ"したらスイッチをオンにしつつまた5.5マス戻ったところから移動再開する全塗りの1マスの"ぶったい"」。


もう少しグラフィカルに説明すると、画像自体は

というただの1マス黒塗りの"ぶったい"で、それを右方向に「速度:はやい」で以下のように動かす。

■□□□□□|

□■□□□□|

□□■□□□|

□□□■□□|

□□□□■□|

□□□□□■|


5.5マス(|の部分)先にぶつかった

■□□□□□|

□■□□□□|


・・・


このぶつかった瞬間に「指定位置から右移動」で戻りつつ「スイッチ:オン」にする。さらに「スイッチがオンならオフにする」を仕込んでおくことで、毎回ぶつかった瞬間に(=一定周期で)スイッチがオンになる"ぶったい"が完成。初期位置をずらすことで、タイミングの変更も可能。

Iter & Next=

"ぶったい"の名前6文字に収まる良い呼称が思いつかなかったので、とりあえずプログラミングの用語である「Iteratorイテレータ)」の省略語「Iter」を使っている。意味としては「一つずつ進むもの」みたいな感じ。


Iter」と「Next」は二つセットで「1マスずつ動く」という挙動を実現するための"ぶったい"。


具体的には、Iterの次の位置にNextが(Iterに対して)くっつくように以下のような感じでセットする。(IがIterで、NがNext)

IN

この状況で、Iterが「Nextの位置に瞬間移動」という処理を行うと次のように変化する。

IN□□□□

□IN□□□

Nextは「Iterのとなりにくっつく」という処理にしているため、IterがNextの位置に来ると、Nextはさらに1マス先に移動する。これを繰り返すことで「1マスずつ動く」という処理になる。
上の「サイクル」のスイッチがオンになるタイミングに合わせて移動することで、「一定周期で1マスずつ動く」という挙動になる。
あとはこれを楽譜の上で移動させて、「Iter:楽譜にぶつかったらスイッチオン(&スイッチがオンの時はオフ)」にすれば「楽譜の■のリズムでスイッチがオンになる」という"ぶったい"がほぼ完成。実際には■が複数並んでいた時に移動しても「ぶつかる」という判定が行われないため、Iterは移動するたびに「■→□」となるアニメを再生する必要がある。


まとめると、

  • Iter
    • 「楽譜」の最初のマスに配置
    • 「サイクル」のスイッチがオンになったら「Next」の位置に移動&1コマ目だけが不透明のアニメを1回だけ再生
    • 「楽譜」とぶつかったら自分のスイッチをオン
    • 自分のスイッチがオンなら自分のスイッチをオフ
  • Next
    • Iterのとなりにくっつくように初期状態を設定

という感じになる。


NextはただIterの隣にくっつけるだけで、特殊な処理は基本的には必要ない。ただ、複数の楽譜を使ったり「改行」に相当するような処理を行う場合のみ、それ用の処理を追加する必要がある。

=問題点=

以上の"ぶったい"さえ作れれば、あとは「楽譜」のマスの画像をいじるだけでリズムの変更が可能になる。ただ、この方法ではいくつかの問題がある。


一番大きいのは「1マス目のタイミングがずれる」という問題。
例えば「IterのスイッチがオンになったらSEを鳴らす」という風にした場合、

「Iterが楽譜とぶつかる」→「Iterのスイッチがオンになる」
↓
「Iterのスイッチがオンになる」→「SEを鳴らす」

という風に1フレームズレが生じるため、SEが鳴るタイミングがズレる。
Iterが直接SEを鳴らすようにしても、複数のリズムを使う場合は

「別のラインに移動する」
↓
「Iterが楽譜とぶつかる」→「IterがSEを鳴らす」

などのようにになるため、ズレが生じる。
1マス目以降は、「サイクル」のタイミングを調整してなんとかなるものの、1マス目のズレだけはその方法では対応できない。
そのため、1フレーム目に楽譜のリズムでSEを鳴らす場合、「1フレーム目は全部オン(orオフ)として扱う」や「リズムは1パターンだけ」や「1フレーム目だけ特別処理」などの対応が必要になる。
ちなみに、サンプルゲームでは「1フレーム目は必ずオフ」という対応を取っている。


他の問題としては「長いリズムだと、一つのラインに収まらない」がある。これは「複数の楽譜を並べる」や「改行のように折り返す」などの対応でなんとかなる。詳細の解説は省略。

=あとがき=

ということで、書いておきたかったことは書けた。


もう少しメイドイン俺は続けるつもりなものの、徐々にTRPGの準備に戻る予定。
書くことがないのと、仕事が佳境なので、次の更新まで1週間くらい間が空くかもしれない。