2019年10月5日に発売されたPasocomMini PC-8001は、1979年の8ビットPCをミニ化した、クラシックな玩具だ。本機には21本のゲームが同梱されており(※)、ゲーム機としても楽しめるほか、N-BASICを使って自由にプログラミングが楽しめる。
※『ラリーX』、『スーパーギャラクシアン』、『ディグダグ』の3本は、2020年9月10日のアップデートにて追加された。
以前の記事では、記者のプログラミング知識がほとんどない(忘れてる)状態からスタートし、ゲームっぽい感じのプログラムを組んでみたところまで実行したが、今回は“実際に遊べるゲーム”として完成までやってみようと思う。
初歩的な知識については、前回の記事である程度解説しているので、ゼロから知識を身に付けたい方は、まずこちらを読んでほしい。
今回作るのはどんなゲーム?
改めて記者(ででお)の自己紹介をしておこう。1980~1990年代に趣味でプログラミングをかじったことはあったが、25年以上が経過し、知識のほとんどは忘れ去った“ほぼ素人”。
前回、画面上に表示されるクイックコマンドリファレンスを参照しつつ、どうにかそれっぽいプログラム“ファミ通ベーダー”を作れるまでリハビリできた。今回は、PasocomMiniのディレクター・郡司照幸氏に助言をいただきつつ、ちゃんと遊べるゲームの完成を目指そうと思う。
郡司照幸氏(ぐんじ てるゆき)
ハル研究所 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点が入る)
PasocomMini PC-8001『ファミ通ダイブ』実行動画
郡司オープニングデモからシームレスにゲームがスタートし、飽きさせないステージデザインで、何回もトライする気になります!
(個人的にはヘリのローターアニメが好きです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をお持ちの方は、ぜひお試しあれ。
この冬はお家でプログラミングを楽しもう!
PasocomMini PC-8001 PCGセットの購入はこちら(Amazon.co.jp)