メインコンテンツへスキップ
見出し画像

MSXのマシン語でアスキーアートのデモを作っていたらあれっぽいゲームができた

    毎度、rorosukeです。

    最近、AIでMSXのマシン語プログラムを作るのに夢中になっているところです。その直近記事がこちらです。ついにカートリッジROMまで作ることができました、という内容になっています。

    これまでに2つのマシン語によるシューティングゲームを作成してきましたが、ここで最初に立ち返ってみることにしました。

    その昔、私も自力でマシン語プログラムを作った経験があるのですが、その一番最初に作ったのは、こんなものでした。



    文字画面に順番に文字を敷き詰める

    BASICプログラムを作ったことのある方ならわかると思いますが、画面を同じ文字で埋め尽くすのに、BASICならばかなり時間がかかります。

    しかし、これをマシン語で実行すると、文字どおり桁違いに速くなります。それこそ、当時の私には、100倍くらい速くなったように感じられ、その衝撃はすさまじいものがありました。

    このプログラムをAIで作ってみました。できたのがこちらです。マシン語は1010〜1040行のDATA文に入っていて、わずか61バイトです。

    10 REM === SCREEN 0 LETTER FLASH (MACHINE CODE FROM DATA) ===
    20 CLEAR 200,&HBFFF:DEFINT A-Z
    30 SCREEN 0:WIDTH 40:KEY OFF:COLOR 15,1,1:CLS:PRINT "LOADING..."
    40 A=&HC000:LN=0:RESTORE 1010
    50 READ N:IF N=0 THEN 90
    60 S=0:FOR J=1 TO N:READ D:POKE A,D:A=A+1:S=S+D:NEXT J
    70 READ C:LN=LN+1:IF C<>S THEN PRINT "DATA ERROR LINE";1000+LN*10:END
    80 GOTO 50
    90 CLS:PRINT "SPACE KEY = STOP":FOR T=1 TO 600:NEXT T
    100 DEFUSR=&HC000:X=USR(0)
    110 SCREEN 0:COLOR 15,4,4:KEY ON:END
    1010 DATA 16,58,7,0,79,243,30,65,33,0,0,12,237,105,0,0,124,993
    1020 DATA 16,246,64,237,121,13,0,0,0,123,22,4,6,240,237,121,0,1434
    1030 DATA 16,16,251,21,32,246,28,123,254,91,32,2,30,65,219,170,230,1810
    1040 DATA 13,240,246,8,211,170,219,169,230,1,32,204,251,201,2182
    1050 DATA 0

    これを実行すると、次のような同じ文字が敷き詰められた画面が、高速に書き換えられていきます。

    画像

    文字(キャラクター)画面を操作するのって、やっぱり楽しいなと思って、次にこんなマシン語プログラムを作ってみました。



    アスキーアート隕石シミュレーション

    ただのデモンストレーションですが、上空から隕石が降ってきて、地面に激突すると激しく破片が飛び散るアスキーアートアニメです。

    実行すると、マシン語プログラムをメモリ上に展開するので、それが終わるまで数十秒お待ちください。

    画像
    画像

    で、これをボーっと見ていたら「これ、見たことあるな」と、懐かしいゲームを思い出しました。それは……



    迎撃ゲームの名作「ミサイルコマンド」

    です。レトロゲーム好きな方ならすぐわかりますが、アーケード版では弾道を先読みして、トラックボールでミサイルを撃墜するゲームです。

    このアイデアを拝借してゲーム化してみることにしました。こうしてできたのが、「スペースインベーダー」のシューティング要素と「ミサイルコマンド」の "基地を守る" という要素を掛け合わせた、

    メテオストーム(流星の嵐)


    です。文字(キャラクター)を使ったフルマシン語のミニゲームです。

    画像
    ゲーム画面です。



    メテオストームのルール

    上空から降ってくる隕石を撃ち落として、地上の6つの基地を守ります。マウス操作対応になっています。

    ■ 基本の操作
    ・カーソルキー、またはマウスの移動で自機(地面の上の白い機体)を上下左右に動かすことができます。
    ・スペースキーもしくはマウスの左ボタンで通常兵器の弾を撃ちます。通常兵器は常に最強で、上だけでなく左上と右上への3方向に撃ちます。
    ・Zキーもしくはマウスの右ボタンで上に向けて爆弾を投げます。爆発の範囲が広く、近くの隕石や敵の弾を巻き込んで連鎖的に壊せます
    ・ESCキーでゲームを終了し、BASICに戻ります

    ■ 画面の見かた
    画面の左上に、SCORE(得点)、STAGE(ステージ数)、BASE(残りの基地数)、SHIP(自機の残数)、METEOR(残りの隕石数)、そしてキー操作の方法が表示されます。

    画像
    ステータス表示部です。

    ■ ステージクリア条件
    本ゲームでは、ランダムに隕石が降り注ぎます。これに連動して、「METEOR(残りの隕石数)」が100個からカウントダウンします。これが0になったときにステージクリアになります。

    画像
    隕石数は100個からカウントダウン。
    0個になったらステージクリアです。

    ■ 特別な敵
    ・UFO(ピンク) 複数同時に現れて、基地を狙って弾を撃ってきます。UFOの弾は基地を壊しますが、自機の弾を当てれば迎撃できます。UFOはステージが進むほど硬くなり、壊すのに必要な命中回数が1、3、5、7、9回と増えます。中央の数字が、あと何回当てれば壊れるかを示しています。当たった瞬間にUFOが白く光ります。

    画像
    ピンクの敵がUFO。
    ステージが進むと、弾を数回当てないと破壊できなくなります。

    ・ビーム砲(オレンジ) 画面の一番上に突然現れ、約3秒、自機の動きを追いかけてから、真下にビームを撃ちます。弾では防げず、ビーム砲そのものも壊せません。ビームが基地に当たれば基地が壊れ、自機に当たれば自機を1機失います。ビーム砲は、ステージ6から2台、9から3台と増えていきます。出現の間隔もどんどん短くなり、ステージ13では3台が最初から並んで自機を狙い続けます。

    画像
    3台並んだ最強のビーム砲。
    ビーム砲は破壊できないので、うまく逃げてください。

    ■ ボーナスと残機アップ
    ステージをクリアすると、残っている基地が1つずつ点滅し、「ザッ」という効果音とともに100点ずつ加算されます。基地を守るほど、得点が増えます。

    画像
    ステージクリア時には、残った基地1つにつき100点のボーナスが入ります

    さらに、得点が5,000点増えるごとに自機が1機増え、壊れた基地が1つランダムに復活します。

    ■ 最終ステージ
    ステージ13をクリアすると、「CONGRATULATIONS!」が表示されて、エンディングです。

    ■ ゲームオーバー
    基地がすべて壊されるか、自機の残数が0になるとゲームオーバーです。

    画像
    自機がゼロになったときのゲームオーバー画面
    画像
    基地がゼロになったときのゲームオーバー画面

    ■ 裏技
    本来ステージは順番に進みますが、ある操作で開始ステージを選ぶことができる裏技があります。



    プレイの方法

    カートリッジROMイメージで公開しますので、これをダウンロードしてから、MSXPenであれば「Load ROM Image」で選択するだけです。

    カートリッジROMイメージ

    起動すると次の画面が表示されます。

    画像

    マウス操作のための切り替え

    本ゲームはキーボードでもプレイできますが、マウス操作に対応しています。ただし、マウス操作をするにはエミュレータ側の設定が必要となることが多いようです。

    MSXPenの場合、通常はマウス操作ができませんが、私の環境では、エミュレータ画面をクリックしてからAlt+Mを押すと、マウスの設定を切り替えられました。自機がマウスに反応する設定になるまで、必要に応じて繰り返してください。

    マウスのアジャスト

    マウス操作を行うには、さらにアジャストを行ってください。アジャストとは、マウスカーソルの位置とMSXの画面内の自機の位置を合わせる調整のことです。初期状態だと、位置が合っていないので、そのままだと操作がしづらく快適にプレイできません。ゲーム途中で画面の表示サイズを変えて、最大化した場合も、マウスカーソルとMSXの画面内の自機の位置がずれますので、そのときもアジャストが必要です。

    アジャストの方法は簡単です。マウスカーソルをMSXの画面の左上と右下に移動するだけです。何度か左上と右下への移動を繰り返すと、徐々にマウスカーソルと自機の位置が合ってきて、最終的にはほぼ同じ位置に表示されるようになります。これでアジャストは完了です。

    画像
    マウスのアジャスト操作。
    赤線のようにマウスカーソルを繰り返し動かすと合ってくる

    アジャストはゲーム中、いつでもできますが、ゲーム開始時に、画面中央に「ADJUST TIME / CLICK TO START」と出ますので、そのときにクリックしなければ、時間に追われずにアジャストできます。



    まとめ:爆発こそ正義

    MSXといえばスプライトなのですが、これまで一切使用していません。その代わりに、キャラクター文字などを使って、アスキーアート的な演出をしてみました。

    こだわったのは、爆発シーン。打ち上げ花火のように、大きく広がる爆発が、しょぼいミニゲームをド派手にしてくれています。

    新たな要素としては、マウス操作にも挑戦してみました。ぜひ全画面モードでプレイしてみてください。その際は、再アジャストをお忘れなく。

    開発としては、最初からフルマシン語で作成しましたが、当初コードはBASIC言語(マシン語はDATA文)で出力していました。しかし、敵の種類を増やしたら、あっという間にメモリ不足です。また、BASICだとローディングに時間がかかる問題もありました。
    そこで、途中からはカートリッジROMイメージを直接出力することにしました。これで、BASICのDATA文からマシン語を展開する待ち時間がなくなり、BASICのローダーを含めた構成で悩んでいたメモリ不足も解消できました。

    こうなると、別のCPUや機種にも挑戦したくなります。AIの力を借りれば、ファミコンのソフトなんかも作れるんじゃないか……と、夢が広がってきますね。

    以上!



    追記:続編を書きました

    ゲームをファミコンに移植しました。

    #MSX #レトロPC #レトロゲーム #ゲーム制作 #自作ゲーム #マシン語 #Z80 #アスキーアート #シューティングゲーム #MSXPen #ROM化 #生成AI #AI活用 #プログラミング #ミサイルコマンド #マウス

     
     
    AIで時間を生み出す実験をしています。 元PC系出版社編集者。 Claude・ChatGPT・Geminiを並行使用しながら、 実践した話だけを書いています。

    あなたへのおすすめ