第九回講義 「簡単なゲームを作ろう—後編— 味付け」

ついにProgramの講義自体は今回で最後となりました。

今回の内容は味付けという事で、昔風の感じのゲームを作ってみたいと思います。


さて、今回は少々高度な知識を必要とするかもしれません。

といいますのも、今回導入したい事柄は・・・



というように4つぐらいあるからなのです。

で、今回これらの中で実際に導入すべき技術は2つあり、



となっており、特に前者の側の「2進化10進法」の導入には強い意義があります。

この2進化10進法というものは、いうがはやいが、単に我々が用いている10進数で内部の計算をしようというもので、一般にComputerは16進数ですが、この後の6つの数字(AからFまで)を無視しようというものです。

まぁ、i8086系では既にこの演算をする為の機能もありますが、本講義ではそれは用いません。といいますのも、私はそれらを使ってやるのがいまいち好きになれないからなのです(理由は後記するとしましょう)。


さてさて、では時間制限などを含んだものにして、かつそれらを表示できるようにしなければなりませんから、まずは画面レイアウトからはじめましょう。

では早速ですが、勝手ながらにこちらでレイアウトを整えたものを示しましょう。



このProgramでは右側に色々を表示し、左側をゲームフィールドとしています。

画面の各部位の表示には前回の講義で導入した仮想VRAM(仮想画面)を使用していますので、然程難しくはないでしょう。

さて、では次に得点を導入してみましょう。



さてここで2進化10進法を採用しているのですが、これ自体は前述しましたように、我々が用いる10進数だけを用いて計算するというものです。Programでは、ScoreAddition Procedure内で実現しています。

そのProcedureを参照していただければおわかりの事と思いますが、内容は実に単純明白で、足算の結果が10を超えると、ひと桁分の桁上がりをするだけになっています。また、計算は1の位から始め(実際には10の位からにしましたが)、それを桁上がりが発生している間演算を繰り返すというだけで、特に難しい事はしていません。

また、その結果を表示しなければなりませんが、この2進化10進法を用いている場合、ASCII Codeに変換するのは実に簡単にできることで、単に30hを足せばいいだけです。ですから、2進化10進法を用いると、大変直観的且つ楽な表示ができるようになっています。またその演算の方法も実に単純で、10を超えたかどうかを判断するだけで済みますので、その実装は大変楽なものです。


プログラミング時まめ知識その5−i8086での2進化10進法−

80x86 Series CPU(MPU)ではDAA(Decimal Adjust for Addition)やDAS(Decimal Adjust for Subtraction)というものがあります。これらを用いると、1 Byte内で2桁の2進化10進法を用いた演算ができるようになっています。

例えば、

        mov     al,035h ;AL := 35h
        add     al,035h ;AL := AL + 35h = 6Ah
        daa             ;AL := 70h

のように、AL-regに対して2進化10進法演算を行った場合の補正が行われるようになっています(35h + 35h = 6Ahで、1の位がAh(=10)の為、桁上がりによって10の位が7となっている)。

これを用いれば、楽にできるように思います。


が、私はこれを使用した事はありません。といいますのも、これらの命令を使用した場合、演算結果を取り出すには1桁毎取り出すのが少々面倒に思われるからです。といいますのも、1 Byteを上位4 Bytesと下位4 Bytesに分けなければならず、それがちょっと煩わしく思うからです。

寧ろ元から1 Byteを1桁とした方が(結果の保存領域では2倍の容量を使用する事になりますが)処理は簡素・明瞭となると思います。

また、下手にこれら高度な処理をもったものを用いるよりかは、極力単純な足算・引算・ビット演算だけでなるべく全ての計算を実現できるようにしている方が、本来のAssembler Programというものであるのではないのかという私個人の哲学がありまして、なるべく高度な命令は使わないようにしているつもりです(とはいえ、mulやdivを用いる事もありますが、それ以外の命令でも、使用しても極力「基本のAlgorithm」自体が崩れにくい命令(movsやstosなど)ぐらいしか使用していません)。


では、次に時間制限をいれましょう。尚、時間は180秒とします。



どうでしょうか。ここまでくると、ほぼ「昔あったような」感じのものという雰囲気になったと思います。しかし、これだけでは何と無く味気ないので、次に音をいれてみましょう(まぁ無理に時間計測まで2進化10進法演算を用いる必要はなかったのですが、どうせですから、ここでも採用してみました(^^;)。

と、音を入れるとはいえ、目的と衝突した場合か、障害物と衝突した場合しか音は出しませんが(まぁ大した音も出してませんけど(^^;)



というようになりましたね。周波数をいぢるというのは、ちょっと作法としては不作法な感じもありますが、昔はこうやって何とか音を出していたという事だけでも味わっていただければというだけのことです。

また、効果音発生中はある程度聞こえるようにする為に、長い時間流す必要がありますので、2〜4ほどの間VSYNCを待つという形でWaitをかけてしまっていますので、多少重さ(ひっかかり)を覚えると思いますが、これでは実用的ではありませんね。実際には割り込み(Interval InterruptやVSYNC Interruptなど)を用いて裏TASKの中で鳴らすのが本来の方式です。

ただ、まぁ簡単に「音をつけたとしたら・・・」というだけですので、そこまで言及したものは作りませんでした(実際に作るとなると、少々Programが長くなりますので、ちょっと避けたかっただけです。またInterruptを使わなくてもいい方法もあるのですが、まぁ処理の複雑化を招いてしまって、余計わかりにくくなりますので、なるべくそういうのは避けようという事で、それさえしませんでした)。


さてさて、以上で一連のProgramの説明というものはこれで終わりになります。

まぁ、あまり説明をしきれていないような感じもあって、単にだらだらと私の汚いSourceを見せただけのようにも思いますが、こんなのでもこれからAssemblerを使われる方の一助となれれば幸いです。

と、ちなみにですけども、今回作ったこの簡易のゲームは、私が初めてPC-6001 mkIIという機種でBASICで作ったゲームをAssemblerでほぼ再現したものなんです。まぁ昔はこの程度のものをBASICで作るだけでもかなり時間をかけた覚えがありますが、今からすれば誰でも作れそうなものですね(^^;(Programの練習には調度いいのかも知れませんが)。


さて、次回講義は最後の蘊蓄になります。Programの説明は一切ありません。単に最初に蘊蓄を述べましたので、まぁ最後にあってもいいだろうという事だけです。

読まれても、単にひとりよがりな事をいってるだけのような気もしますので、無意味かもしれませんが(まぁ最初の蘊蓄でもかなりのひとりよがりでしたが)、読む気のある方は読んであげてくださいな(ってこの講義室の内容を最後までちゃんと読んでる人がいるのかどうかさえ、疑わしいのですが(^^;;;)

では、次回講義は「後書き 〜最後の蘊蓄」です。


Back


手元に実機も実行環境もありませんのでサポート不可です。

文章は執筆当時のものをそのまま掲載していますので、時代・時節と合わない表現が含まれています。

また、一部に半角カナ文字が使用されています。