MZ80を起動せよ!とりあえずBASICでゲームを作ってみようよ

以前、無事にMZ80が起動しBASICも立ち上がりました。

ここまできたらあとはプログラミングをしてゲームを作ったり、外部ストレージをつなげたりとかなんですが、このMZのBASICはいままで触ってきたBASICとはちょっと癖が強いのと、速度が遅くて作りづらいというのがります。なので、本格的なアクションゲームを作ろうと思ったら疑似スクリーンバッファを作成しアセンブラで転送するシステムを作る必要があるんですね。


一応z80のアセンブラは触ったことがありますが、それはシングルボードコンピューターでしたのでこういった「一定のエリアでメモリを割り当ててアセンブラと並行する」っていうのが全然わからないんです。なのでとにかくBASICだけでゲームを作ってみようというわけです。

じゃあ問題はゲームの要素を一通り作れてBASICでも十分な速度が楽しめるゲームって何かって話なんです。

■ゲームの要素を満たしたシンプルな「ゲーム」

まず、ざっくりゲームの流れをば。

1)タイトル

2)プレイ画面

3)ゲームオーバー画面

以上の3つなんですね。「は?クリア画面は?」ってなると思うんですけど、ゲームオーバーってなんか「失敗!」ってイメージあるんですけどあれ「ゲームが終わりました」って意味なんですよね。なので昔のアーケードとかゲームクリアしても最後「ゲームオーバー」って表示されるんですよ。後味わりい!!!!!!某パンツ一枚の騎士さんのゲームとかBGMがゲームオーバーのままなのでもうやるせないです。

話が脱線しました。

ゲームの流れは上の3つですが、まあどんなゲームを作っても上の要素があればまとまって見えるわけです。問題は2番の「プレイ画面」。

ぶっちゃけ個々の中身を分解すべきなんですがたぶんこういう要素なんです。

1)プレイヤーが操作できるもの

2)プレイヤーの操作の影響を受ける動くもの

3)何もしていないとMissになるもの

4)クリアすべき課題

5)得点

以上のものを満たし、簡単に作れるものっていうとたぶん、

ブロック崩し

なんですね。何が強いってボールが2と3の要素を兼ねてるんですよ。ここがすごい。

というわけでちょっと作ってみました。

■どういう構成にすればいいのか考えてみる

基本、自分でBASICを描くときには1-100の間をmainloop関数として使用し、各機能ごとにGOSUBで飛んで処理するようにしています。(これが恐ろしく重くなる一因でもあるのですが)。

なので、基本的にSUBルーチンで呼ぶブロックとして考えてみます。

1)タイトル画面

2)変数リセット・初期画面描画処理

【ここからゲームプレイ処理】

3)キー入力受付

4)パドル動作

5)ボール移動処理

6)ブロック判定・得点

7)ミス判定

といった形で流れを分離し、回していけば形になるんじゃないでしょうか。

そんな感じで考えながらコード書いたのでまあ見事なスパゲッティになりました。

この規模でこのスパゲティですからね。1画面プログラミングしてる人とかすげえと思う。

【BREAK OUT】

■出来上がったものがこちら

タイトル画面。DONKEY CONGの画面をイメージしてみました。

右側に得点を表示するスタイル。きちんとコンティニュー機能があります。


あっさり作ってみた割にはけっこう遊べるものが出来上がりました。

ゲーム自体シンプルなのと、先ほど書いたGOSUB式によって機能の追加がかなり容易になっています。が、もし一本大きなゲームを作るとなったら絶対ダンプリストを出力し、変数の管理などを監視しなくてはならないのでプリンターなどの外部出力機能は必須です。なにせ40*25行しか表示できないので、到底管理しきれないのです。また、コピーなどはできることはできますが、行管理のため間違えて上書き&一つ戻るコマンドがないので結構厳しいです。

■結局のところ、純粋なBASICのみでは実用的なアプリは難しい?

たぶん、描画の更新が多いアプリケーションは実用は難しいと思います。

一応、print文に関しては当時多くのユーザーが直面した問題だったようで解決方法がインターネットに記載されていました。また、実は今回のプログラミングでも一部特殊な処理を使用しております。それがこちら。

【連続したキー入力を可能にする方法】

10 GET A$:POKE$1170,1:GET B$:POKE$1170,0
20 IF A$="A" THEN RINT "A";:REM ここのタイミングでキーを押すたびにやりたいことを書く
30 GOTO 10

※参考サイト:Enri's Home PAGE

ものすごくお世話になってます。こんなすごいサイトが今でもかなりのペースで更新され続けているのはインターネットの最後の良心かもしれない。

こちらを使用することにより、押しっぱなしでの移動が可能になります。あともう一つトリッキーなコードを書き込んでBASICのフレーム監視プログラムを開放すると、さらに早くなります。しかしながらそれでも遅いことには変わりないので、最終的にはブロック転送によるスクリーンバッファを目指そうと考えています。一回全画面アセンブラによる描画を試してみたのですがこれがすごく早い。スクロールアクション系などには必須のテクニックになるはずです。それ以上に、ステージマップ情報をどこに保持するのかとかいろいろ問題はありますが。40x25=1000byteなので、一画面で1kbyteものデータが必要なんですね。絶対圧縮とか必要。だって34kbyteぐらいしかないんだもの・・・たぶん、4*4のテキストテクスチャを作成して、パターンを呼び出すルーチンで圧縮を図るといいかも。

といった感じで、目的のゲーム作りはひとまず完了です。割と面白かった(*´ω`*)

ここのところ話題に見かけるIchigoJamとかは4kbyteしかメモリがないので、これよりもきついメモリエリアでゲームを作るわけですが、正直きつすぎます。文字を書き換える機能がありますけどそれだけでもメモリいっぱいになるそうで、外部EEPROMのデータをとっかえひっかえする必要があるわけですよね。いやきついと思う。一画面ゲームがせいぜいじゃないかなぁ

あ、でもPCG-8000とかを使うとMZ-80でもかなり細かい絵を作ることができます。まずそのマシンの入手が鬼ほど難しいのであきらめて既存の文字コードで絵を作るしかなさそうですけどね。それがMZの魅力ですし。

次回は外部接続端子からの出力実験か、画面スワップ実験をやってみたいと思います。

あわよくばデジゲー博とかで空気も時代も読まないゲームを展示したい所存。


それではまた次回!

次の記事:


MZ80を起動せよ!MZTファイルを実機に読み込ませてみた



前回の記事:

MZ80を起動せよ!公式BASICを読みこませてみた結果

コメント

このブログの人気の投稿

ファミコンの完全自作ROM&カセットを作ろう!!その1~立ちはだかるコンパイラの壁~

ファミコンの完全自作ROM&カセット作ろう!〜cc65で起動ROMをつくる〜

74HC595を使ってarduinoの16ビットパラレル出力に挑んでみた