11 |
BSVの設計トライアル (21) |
ゲームFSMのアルゴリズム
トライアルの結果、BSVによるゲームFSMが完成しました。過去記事のステートベースのサウンドステートマシンと異なり、ステート分解をしていないため、rule文を一切使用していません。全てbsc(Bluespec Compiler)の、StmtFSMライブラリにステート管理を任せました。
基本的にはCで記述するようにゲームが記述できることが分かりました。例えば、弾の移動及び衝突判定、衝突処理(爆発マーク)、爆発マーク消去等のアルゴリズムを考えると、自弾、敵弾共にアルゴリズムは共通で、疑似コードで書けば、
if (弾爆発タイマ >= 1) { // 弾爆発中
弾爆発タイマ++;
if (弾爆発タイマ == MAX) {
弾削除; // 論理的な消去
弾爆発マーク消去; // 物理的な消去
弾爆発タイマ停止;
}
} else {
if (弾が出ていない and 弾生成条件) {
弾生成処理;
弾発射音; // 自弾のみ
}
if (弾存在) {
衝突判定;
if (対象物) { // 自弾の場合はインベーダ及びUFO、敵弾の場合は自機
弾削除; // 論理的な消去
対象物ステート <= 爆発;
対象物爆発タイマ <= 0;
} else if (上下ハズレ || ベース || 弾) { // 弾:自弾の場合は敵弾、敵弾の場合は自弾
弾マーク消去;
弾爆発マーク;
弾爆発タイマ <= 1;
} else { // 衝突していない場合
弾を進める;
}
}
}
一方、対象物は、
if (対象物ステート == 爆発) {
if (対象物爆発タイマ==0) {
対象物爆発タイマ <= 1;
対象物爆発音;
対象物爆発マーク;
} else {
対象物爆発タイマ++;
if (対象物爆発タイマ == MAX) {
対象物削除; // 論理的な消去
対象物爆発マーク消去; // 物理的な消去
}
}
}
のようになりますが、StmtFSMを使うと、このようなシーケンスをクロック毎のステートに分解しなくて記述できます。
インベーダのタイミング
某所で質問があったので、タイミングについて解説します。基本の1 tickは1/60秒で、その中で、インベーダ1匹、敵弾全弾、自機、自弾、UFO、スコア等の処理を行います。以下は実際のBSVのメインループのコードです。
while (game_flag) seq // メインループ
for (noy <= 0; noy < `Inv_TateS; noy <= noy + 1) seq // インベーダの行処理
for (nox <= 0; nox < `Inv_YokoS; nox <= nox + 1) seq // インベーダの列処理
if (inv_s[nox][noy]) seq // インベーダが生きてれば
ivader; // インベーダ処理
gun; // 自機処理
bullet; // 自弾処理
for (idx <= 0; idx < extend(max); idx <= idx + 1) seq
invBullet(idx); // 敵弾全弾処理
endseq
ufo; // UFO処理
scores; // スコア表示
endJudge; // 終了判定
counter <= counter + 1; // tickカウンタ++
wait_timer; // インナーループを1/60secにするウエイト
endseq
endseq
endseq
endseq
gameOver; // ゲームオーバー表示
1tick=1/60secの間に、インベーダ1匹(2ピクセル移動)の処理に対して、自機(1ピクセル移動)、敵弾(1ピクセル移動)、自弾(4ピクセル移動)の処理が行われます。インベーダは初期に55匹存在するので、1/55倍のスピードで始まりますが、最終的に1倍のスピードになります。従って、インベーダを倒すたびにインベーダ全体は速くなり、一方その他の速度は変わらないわけです。
FPGAでの実装では1 tick内にインベーダ全体を移動することは可能ですし、そのような実装も見ますが、ゲーム性が変わってしまいます。具体的には、インベーダ全体の速度が次第に速くならなかったり、後ろのインベーダを撃つことができなくなります。
例えば、インベーダゲームのレインボーは、後ろのインベーダを撃つことにより出現します。インベーダは残りが一匹になると左へは2ピクセルずつ右には3ピクセルずつ移動します。下2段のインベーダは、左右2ピクセルまでの移動では跡が残らない図形になっていますが、3ピクセルだと跡が消えずに残ります。もちろん今回の実装でもレインボーを体験できます。
ゲームFSMの完成
図254.1は、BSVで再設計したゲームFSMにより動作する、インベーダーゲームの動画です。過去記事に書いたように、サウンドが4ch同時発声と高品質になりました。