PasocomMini PC-8001 特別プログラミング企画。プログラミング素人がN-BASICでゲームを完成させてみた
文:ででお 2019年10月5日に発売されたPasocomMini PC-8001は、1979年の8ビットPCをミニ化した、クラシックな玩具だ。本機には21本のゲームが同梱されており(※)、ゲーム機としても楽しめるほか、N-BASICを使って自由にプログラミングが楽しめる。 【この記事の画像をもっと見る】 ※『ラリーX』、『スーパーギャラクシアン』、『ディグダグ』の3本は、2020年9月10日のアップデートにて追加された。 以前の記事では、記者のプログラミング知識がほとんどない(忘れてる)状態からスタートし、ゲームっぽい感じのプログラムを組んでみたところまで実行したが、今回は“実際に遊べるゲーム”として完成までやってみようと思う。 初歩的な知識については、前回の記事である程度解説しているので、ゼロから知識を身に付けたい方は、まずこちらを読んでほしい。 PasocomMini PC-8001アップデート記念企画。プログラミング素人がN-BASICに挑戦してみた https://www.famitsu.com/news/202009/23205558.html 今回作るのはどんなゲーム? 改めて記者(ででお)の自己紹介をしておこう。1980~1990年代に趣味でプログラミングをかじったことはあったが、25年以上が経過し、知識のほとんどは忘れ去った“ほぼ素人”。 前回、画面上に表示されるクイックコマンドリファレンスを参照しつつ、どうにかそれっぽいプログラム“ファミ通ベーダー”を作れるまでリハビリできた。今回は、PasocomMiniのディレクター・郡司照幸氏に助言をいただきつつ、ちゃんと遊べるゲームの完成を目指そうと思う。 ――というわけで郡司さん、今回はよろしくお願いします。 郡司 さっそくですが、今回はどんなゲームを作るつもりですか? ――えーと、スピード感があって、壮大でかっこいい感じのゲームにしようかと思います! 郡司 ……。プログラミングを始める前に、具体的な内容を書き出してみてはどうでしょうか。 ――いきなりのダメ出し! ちょっといまから考えます……。 郡司 それと、今回も基礎的なBASICコマンドで作成するんですよね。あまり壮大すぎる内容だと頓挫しちゃうかもしれませんよ。 ――た、確かに。では今回もPRINT文でキャラクターを描くことにします。でもスピード感は表現したいなあ。あれ? PRINT文でスクロールって表現できるのかな? 郡司 できますよ。たとえば、1画面に収まらないプログラムリストを表示したり、リターン(Enter)キーを押し続けたりするとどうなりますか? ――文字が上にスクロールして……ハッ! これがスクロールか! 郡司 その通りです。まずは、それをプログラムに起こしてみましょう。 ――やってみます! 最初にWIDTH文で画面内の文字数を40×20に設定してと……(カタカタカタ)。いちばん上のY座標は0で最下段は19行目になるから……こうかな? ――あれ? スクロールしない。 郡司 画面外に描いちゃっていますね。19行目は通常、ファンクションキーの表示があるため、改行でのスクロール送りが判定されるのはもう1行手前になります。 ――そうなんですね! では20行目のY座標を18に変えて……と。 郡司 よくできました。この手法だと上方向のみの疑似スクロールになりますが、今回はこちらを利用してゲームを作ってみては? ――上方向にスクロールするということは、自分は下に進む感じか~。オーソドックスなレースゲームを作ろうとすると違和感がありそう。スキーで滑ったり、パラシュートで飛び降りるとかかな? (30分後) ――まとめました! 今回はこんなのにしようかと思います。 郡司 おっ、早いですね。どれどれ……? ――とある校了日、ファミ通編集者は焦っていた。「あと5分で入稿しないと、記事が落ちてしまう!」かくなるうえは、秘密のヘリで印刷所の上空へ急ぎ、“急降下入稿”をするしかない……という物語のゲームです! ファミ通ダイヴ(仮称) 2000メートル上空からスタート。 ランダムで出現する障害物(*)を避けながら地上を目指す。 障害物にぶつかるたびにライフが減り、ライフがなくなった状態でさらにぶつかるとゲームオーバー。 郡司 なかなかよさそうですね。まずは先ほどのプログラムを改造して、障害物のルーチンを作ってみましょうか。 ――やってみます! ランダムは“RND(1)”で0~1.0未満の乱数を返すから……こうかな? ――弾幕っぽくできた気がする! 郡司 いい感じですね。つぎは自機を動かしてみましょうか。 ――展開が早い! 自機は前回と同じように、“INKEY$”でキー入力を判定すればいいかな。 郡司 ちょっと待ってください。じつはINKEY$ だと、キーを押しっぱなしにしていても、最初の一回しか 判定されないんですよ。 ――なんと! 言われてみれば前回のときは確かに、キーをポチポチ押し直さないと移動ができませんでした。どうすれば……。 郡司 特殊関数の“INP”を使ってみてはどうでしょう? INP(n)・・・I/Oポートのn番から値を取得する特殊関数 ――あ、I/Oポート? 郡司 F11キーを押してウィンドウの18ページ目と19ページ目を開いてください。 ――先生、見かたがわかりません! 郡司 INP(n)のn番というのは、左端に表示されている00H~09Hのことを示します。こちらは16進数で表示されていて、n番目の列が何も押されていない場合は2進数で“11111111”を返し、押された場所だけが0になります。 ――えーと、つまりINP(0)は“4”なら“11101111”、“6”なら“10111111”を返すってこと? 郡司 その通り。それぞれ10進数に変換すると、以下になります。 [4]キーが押された・・・INP(0)=【2進数では】11101111=【10進数では】239 [6]キーが押された・・・INP(0)=【2進数では】10111111=【10進数では】191 ――ここまでわかれば、あとはイケそう! とりあえずそこだけ組んでみようっと。 ――うおお、押しっぱなしでスイスイ動く! あ、画面外にはみ出てエラーになっちゃった。 郡司 画面外に出さないようにするのは、条件を付け加えるだけなので説明不要ですね。これを先ほどのプログラムと合体させてみましょう。 ――やってみます! えーと、さっきのをそのまま使うと変数が被っちゃうから、"*"のX座標はTに変えておこう。自機の行動制限もIF文に足してと……ッターン!(リターンキーを叩く音) ――たったこれだけのプログラムで、スクロールする中で自機を動かせてる! なんだか感動してきた。 郡司 これに当たり判定を付けたら、とりあえずゲームの形になりますね。 ――あれ? そういえば当たり判定ってどうすればいいんだろう。20行の“RND(1)*39”を過去何回分か残しておいて、自機の座標に来たときに判定するとか……? 郡司 そういう方法もありますが、今回はVRAMに対しての直接的なPEEK文で判定してはどうでしょう? ――PEEKって何だろう……困ったときのF11先生で調べてみよう。ポチッとな。 PEEK(addr)・・・addr番地のメモリ内容を取得 ――ほぇ~。先生、自分の脳がピークです! 郡司 あきらめないで、24ページ目を見てみましょうか。 ――ほほー。画面は1マスごとにそれぞれ番号で管理されているわけか~。 郡司 今回のプログラムは40桁モードなので、以下のようになります。 F300 F302 F304・・・F34E F378 F37A F37C・・・F3C6 F3F0 F3F2 F3F4・・・F43E (以下省略) ――なんかややこしいから、エクセルにまとめておこう。自機の座標に当たったときに、その番地をPEEK文で調べればいいのかな? 郡司 試しに、左上に“*”と打って、その番地の文字を調べてみては? ちなみにキャラクターコードは以下の表から割り出せます。 ――えーっと、“*”は16進数で“2A”になるから10進数に変換してと……。42になれば正解なのかな? とりあえず左上の座標“F300”を……ああもう、変換はめんどうだから16進数のまま書きたい! 郡司 16進数で数を表す場合は、数字のアタマに“&H”とつければいいですよ。 ――それ、すごく助かります! さっそく左上に“*”をポチッと置いて、PRINT文でダイレクトに表示してみよう。 郡司 “*”のキャラクターコードである42が表示されましたね。正解です。 ――完全に理解できた! さっきのプログラムに組み込んでみようっと。自機(クローバーマーク)で上書きする前にPEEK文で判定すればいいか。 さっきエクセルにまとめた表を見ると……自機のX座標が0のところは&HF6C0だから、Xの位置で2ずつ増えて……こうだ! ――やりました! ついに! 郡司 かなりゲームの形になりましたね。 ――たった9行のプログラムでこんなにゲームっぽくなるなんて……もっと長くなるかと思ってた。あとはタイトル画面や装飾、ゲームバランスの調整をすれば完成かな。 郡司 そのあたりを追加しているうちに、プログラムが何倍も膨れ上がるんですけどね(ニヤリ)。ともあれ、基本部分はできたので、あとは長さは気にせず完成まで進めてみてください。 ――腕が鳴りますぞ。あ、その前に質問がふたつほど! 画面をカラフルにするにはどうすれば? あと、ステージにバリエーションを増やそうかと思うんですが、IF文だらけになっても大丈夫ですかね? 郡司 まずひとつ目ですが、プログラムの最初にCONSOLE文でカラーが使えるようにできます。書式はこちら。 CONSOLE[スクロール開始行][,スクロール行数][,ファンクション表示スイッチ][,カラー/白黒切替] ――画面下のファンクション表示もオンオフできるんですね。どうせなら消しておきたいな。 郡司 今回はCONSOLE 0,20,0,1とすればいいでしょう。あとはCOLOR文で文字の色を好きに変更できます。 COLOR 色番号 郡司 ただし、カラーモードをONにしたときは、 横方向の表示が1マス減ります。つまり、(WIDTH文で40桁x20行表示の場合)LOCATE文で指定できる 範囲は0~38, 0~19 までとなるのでご注意ください。 ――なるほど~。自機や障害物がはみ出さないように気を付けないと。 郡司 ふたつ目の質問については、ON~GOTO文を使うことでスッキリします。書式はこちら。 ON 式 GOTO 行番号(,行番号……) ――“式”の部分はどうすれば……IF文みたいなもの? 郡司 “式”には1以上の整数が入ります。“ON A GOTO 100,200,300”とした場合、Aが1だと100行へ、2だと200行へ。3だと300行へGOTOするわけです。 ――まさにGOTOキャンペーン! 郡司 以上をふまえて、プログラムを完成させてみてください。 ――よーし、壮大なゲームを目指してがんばるぞ~! 【数日後】 ――で き ま し た ! ファミ通ダイブ 操作方法 キーボードの[4]と[6]で主人公(クローバーマーク)を操作。 ステージ構成(全4ステージ) ステージ1(高度1999~1500メートル) 落下速度がゆっくりなステージ。“*”に当たるとミスになる。ここで操作に慣れておこう。 ステージ2(高度1499~1000メートル) 高速スクロールステージ。ランダムに曲がりくねる煙突の中を落下していく。 ステージ3(高度999~500メートル) ボーナスアイテム(ハートマーク)が登場。ひとつ30点なので、スコアを稼ぐチャンス。 ステージ4(高度499~0メートル) 障害物マシマシな最終ステージ。落下速度はステージ2と同じ。悠長にボーナスアイテムを取る余裕はない? 地上までたどり着けばエンディング ボーナスアイテムの取得数(各100点)と残ライフ数(各1000点)がスコアに加算される。 (じつは、ボーナスアイテムをひとつも取らなかった場合は、“パシフィストボーナス”として8320点が入る) 郡司 オープニングデモからシームレスにゲームがスタートし、飽きさせないステージデザインで、何回もトライする気になります! (個人的にはヘリのローターアニメが好きですw) さらにステージとステージのつなぎに、ちょっとした演出があって、ゲームとしてメリハリが付いている点も見逃せません。 にしてもステージ4はエグい……。 入稿も命がけですねw ――ふだんの仕事をうまくゲームに生かしました!(そもそもギリギリになる前にスケジュール管理を……ということは考えない) プログラムはこちらです。もとは9行だったのに、タイトル画面とオープニングの演出に凝りすぎて164行の膨大なプログラムになっちゃいました。 プログラム概要 100~130行 スクリーンサイズやカラーモードなどの設定 140行 タイトル画面のサブルーチン(840行)に飛ばす 150行 オープニングデモのサブルーチン(590行)に飛ばす 170行 ゲーム開始時の初期設定 180~330行 メインルーチン 340~420行 エンディング 430~480行 ゲームオーバー 490~540行 ミス(障害物*に当たったとき)の処理 550~580行 ボーナスアイテムを取ったときの処理 590~830行 オープニングデモ 840~1100行 タイトル画面 1110~1190行 進行フラグ(F)の判定 1200~1410行 ステージ別の処理 1480~1530行 リザルト表示 1540~1580行 パシフィストボーナス演出 1590~1650行 ゲームオーバーおよびエンディング時のスコア加算演出 変数表 A、I:数値汎用 A$:文字列汎用 X:自分のX座標 T:地形を描写するときのX座標 F:進行状況のフラグ(高度に合わせてフラグが変化) F=1……ステージ1 F=2……ステージ1と2のつなぎ F=3……ステージ2 F=6……ステージ2と3、およびステージ4と地上のつなぎ F=4……ステージ3 F=5……ステージ4 F=6……地上が見える高度(高度10~0メートル) H:自分の高度(メートル) L:ライフ S:スコア C:ハイスコア B:ボーナスアイテム(ハートマーク)を取った個数 W:ウェイト(0は最速、多いほどゆっくりになる) 郡司 ステージを変数Fだけで上手く管理していますね。また変数Wで速度調整をしているだけでなく、演出に転用している工夫もグッドです! ただ気になった点として、残り何メートルかわからなく、ちょっとじれったく感じたので、以下の2行を追加すると、さらにゲーム感がアップするので、オススメです。 130 WIDTH 40,20:CONSOLE 1,20,0,1:DEFINT A-Z:C=832 325 LOCATE 15,0:PRINT H;"m " ちょっとだけ説明すると、130行のCONSOLE文の一番目の数値が0から1になっています。 これはスクロールする最初の行を指定しています。 つまり0行目はスクロールしないんですね。 よって一番上に残り何メートルと表示させても、文字が残ります。 ――郡司さん、アドバイスありがとうございました! CONSOLE文はそういう使いかたもあるんですねー。せっかくだからスコア表示も足してみようかな……。俺のプログラミングチャレンジは、これからも続くぜ! 年末年始はプログラミングで過ごしてみては? というわけで、初心者同然の知識からスタートしたプログラミング企画だったが、無事に1本のゲームを作ることができた。達成感がすごいので、プログラミング未経験の方も、ぜひ短いプログラムからチャレンジしてほしい。 また、今回のプログラムを改造して、自分なりのゲームに仕上げてもいいだろう。こちらのプログラムは、PasocomMini公式WEBサイトから直接ダウンロードできるので、PasocomMini PC-8001をお持ちの方は、ぜひお試しあれ。 この冬はお家でプログラミングを楽しもう!
【関連記事】
- 『My Time At Portia』がEpic Gamesストアで12月28日1時まで無料配布。探検・農業・採掘・恋愛など、さまざまな要素が楽しめるスローライフRPG。日本語にも対応!
- 【週間PVランキング】アニメ『鬼滅の刃』柱合会議・蝶屋敷編に注目が集まる。Switchソフトセール情報も人気【12/18~12/24】
- ゲームクリエイター110人が語る2021年の抱負。キーパーソンたちの言葉から、2021年のゲーム業界がわかる?【年末特別企画】
- 『RO』グッズの期間限定リアルショップ“ラグナロクオフライン”が、2021年1月2日から池袋PARCO別館P'PARCOにオープン!
- 『天穂のサクナヒメ』農林水産省が開発スタッフへ直撃取材! インタビューから判明した大ヒット稲作ゲームの誕生秘話とは?