人生一度はやってみよう MSX Basic 入門
10.避けるだけの簡単ゲームを作ろう
もしも他のプログラミング言語に興味があるならスクラッチなどオススメです。
当サイトにも入門ページがあるので、覗いてみてください。
ブロックタイプの命令を使うビジュアルプログラミング言語です。
私はどちらも好きです。それぞれに良さがあります。
同時進行で学習するのも楽しいですよ。
はじめてのゲーム作り
命令の使い方ばかり学習しているのもつまらないですね。
これからはゲームを作っていきましょう。
手始めに、障害物を避けるだけの簡単なゲームを作ろうと思います。
作業を始める前に WebMSX を再起動してください。
(ページを更新するか、新しく開き直す)
なお、プログラムの入力作業はスクリーンモード0で行います。
ゲームはスクリーンモード1で動かします。
screen 0 [エンターキー]
を実行してから始めてください。
それからプログラムを入力するとき便利なAUTO命令があります。
これを実行すると行番号を自動で表示してくれます。
auto [エンターキー]
試しに使ってみてください。
行番号70の入力が終わり80が表示されたとき
Ctrl+c(Macではcontrol+c)でAUTOを解除できます。
実行したらカーソルキーの左右で、文字Oを動かしてみましょう。
動かすと連続して表示されます。
これは文字Oを消す処理を入れてないからです。下図のように表示されます。
プログラムの説明です。
10 SCREEN1:WIDTH32:KEYOFF
スクリーンモードを1にして、WIDTHを使って
1行に表示する文字数を 32 文字にしています。
ちなみに、初期状態の 32x24 モードは 29文字に設定されています。
KEYOFFはファンクションキーの表示をやめます。
表示するにはKEYONを使います。
20 X=16
変数Xはプレイヤーのx座標です。16は初期座標になります。
30 A=STICK(0)
変数Aには、カーソルキーの押された方向が入ります。
40 IF A=3 AND X<30 THEN X=X+1
右カーソルキーが押されて、さらにXが30より小さければXに1を足します。
つまり、右移動します。
50 IF A=7 AND X>1 THEN X=X-1
左カーソルキーが押されて、さらにXが1より大きければXから1を引きます。
つまり、左移動します。
60 LOCATE X,8:PRINT"O"
座標(X,8)に文字Oを表示します。
70 GOTO 30
行番号 30 へ処理をジャンプさせます。
WIDTH と KEYOFF 以外は前に説明したものばかりです。
「なんかよく分からない」と感じたら、「変数と代入」ページから読み直した方が良いかもしれません。
終了処理を入れよう
このプログラムを終わらせるには、中断するしかありません。
Ctrl+Fn+F9で中断しましょう。(Windowsの場合)
(ファンクションキーがちゃんとあり Fn キーが無いときはCtrl+F9)
(Mac ではcontrol+fn+F9)
次はSCREEN 0でスクリーンモードを変えます。
本当は好きなモードで作業すればいいのですが、スクリーン1では見辛いのでスクリーン0に変更します。
しかし、待ってください。
毎回、中断してはスクリーンモードを変更するなんて面倒です。
そこで終了処理を入れます。
行番号 62 と 65 を追加します。
62 A$=INKEY$
変数A$に押されているキーの文字を入れます。
押されていなければ空文字(ヌル)が入ります。
65 IF A$="e” OR A$="E” THEN SCREEN0:END
もし A$ に文字e、または 文字Eが入っていれば、スクリーンモードを0に変更してプログラムを終了します。
大文字と小文字の両方を比べている理由は、キーを押したとき
どちらのモードになっているか分からないからです。
キーを押したとき反応がなければ、プログラムがバグ(不具合)っていると思われてしまいます。
出来るだけプレイヤーが戸惑わない作りにしていきましょう。
Eキーを押せば終了させられるようになりました。
行番号が汚くなったのでRENUMを実行して整理します。
障害物を表示しよう
障害物を表示します。
障害物には *(アスタリスク)を使います。掛け算で使う奴です。
これをランダムに表示します。
行番号 62 と 65 を追加しましょう。
62 E=INT(RND(1)*30)+1
変数Eに1から30までの乱数を入れています。
この変数は障害物のx座標として使います。
RND(1)は0以上1未満の乱数を発生させます。
これに30を掛ければ、0から29.999999…の乱数になります。
INTは整数にする命令です。つまり 0から29の数にします。
1を足すことで1から30までの乱数を作れる訳です。
65 LOCATE E,23:PRINT”*“
y座標23は、画面の一番下の行です。
この行に表示をすると、自動的に1つ上にスクロールします。
実行してみてください。
下から*が湧き出てきます。
画面全体がスクロールするとプレイヤーキャラの文字Oもスクロールします。
左右に操作すれば、ヘビのようにくねくねと動きます。
当たり判定を入れよう
今回&マークの入力があります。
アンド、または、アンパサンドと呼ばれています。私はアンドですね。
このキーは下図の位置にあります。
いよいよ当たり判定を入れます。
これで*は本当の障害物として生まれ変わります。(大袈裟?)
作業の前に RENUM を実行しましょう。
行番号 52, 55, 82, 85 を追加、110 を変更します。
実行したら操作せず、*に当たるまで見守ってください。
止まったとき、Eキーを押すとプログラムは終了します。
52 V=VPEEK(&H1800+8*32+X)
文字Oを表示する場所のデータを読み取り、変数Vに入れます。
後ほど詳しく説明します。
55 IF V=42 THEN 85
42 はキャラクターコードです。
文字や記号はすべてキャラクターコードで管理されてます。
詳しくは次のページを参照してください。
[ MSX キャラクタコード表 ]
42 とは *(アスタリスク)のキャラクタコードです。
読み取ったデータが*であれば、行番号 85 へジャンプします。
82 GOTO 30
今まで行番号 110 で行なっていたことを 82 行に持ってきて、終了処理をループから外します。
85 REM - - game over - -
REMより後ろにある文字はプログラムとして認識されません。
処理内容などのコメントを書くことでプログラムを読み易くします。
110 GOTO 90
終了処理を受け付けるだけのループを作っています。
次のために RENUM しましょう。
画面の情報を読み取ろう
当たり判定をするには、移動先に障害物があるかどうか調べる必要があります。
今回の方法は、VRAMを使っています。
VRAM とはビデオメモリとも呼ばれ、表示する情報はすべてこの装置に記憶されます。
言い方を変えると、VRAM の内容が画面に表示されているのです。
ですから VRAM 上のアドレスを調べることで、何が表示されているか調べることが可能なのです。
60 V=VPEEK(&H1800+8*32+X)
VPEEKは VRAM 上のアドレスを指定することで、内容を取得できます。
&H1800は表示するもののキャラクタコードが格納されています。
VRAM を使った例です。
試すときは WebMSX をもう一つ別のページに新しく開きましょう。
VPOKEは VRAM の指定したアドレスへキャラクタコードを書き込むことができます。
実行してみると、画面の4つの隅に A B C D と表示されました。
それぞれのコードは A(65) B(66) C(67) D(68)です。
VRAM のアドレスと画面表示の関係が分かると思います。
ただし、これはスクリーンモード1(32x24)の場合です。モードが変わればアドレスも変わります。
なお、&H1800は 16 進数の書き方です。
16 進数を使う理由は、MSX の資料でアドレスについて書かれたものは、
すべて 16 進数で表記されているからです。
慣れてくると「これは画面表示のアドレスだな」とか「これは文字の絵のアドレスだ」などとパッと見て分かるようになります。
プログラムの説明に戻ります。
80 LOCATE X,8:PRINT"O"
座標 X,8 に文字Oを表示しています。
この座標をアドレスに変えるときは832+Xという計算式になります。
32 はスクリーンモード1の横幅です。
文字Oは Y 座標が 8 に固定されています。なので32を掛けるだけです。
(もし Y 座標も変数ならY32+Xになります)
60 V=VPEEK(&H1800+8*32+X)
画面のデータを読み取るアドレスは&H1800から始まります。
文字Oを表示するアドレスは、結局、&H1800+8*32+Xになるのです。
長くなってしまったので、次回につづきます。