ふろく

ホーム > ふろく > BASIC講座 > パソコンミニPC-8001でゲームを作ろう! 第二回
BASIC講座

パソコンミニPC-8001でゲームを作ろう! 第二回

OP

今回から実際にプログラムを組んでいきます!
(ちょっと地味な作業はありますが…)
楽しんでいってね。

Hello World!

まずは、どんなマシンでも基本中の基本、「どこ」に「なに」を表示するかです。
とりあえず演習する前に画面をクリアしてしまいましょう。CLRキーを押して下さい。
(JPキーボードでは漢字キー、または全角/半角キーと表示されているキー)

以下を入力してRETURNキー↓

とすると画面の中央に草が生えましたw

LOCATE文は、表示座標を指定する命令です。
1つ目の数値がX座標、2つ目の数値がY座標です。数値間はカンマ(,)で区切ります。
LOCATE X座標,Y座標

もちろんPRINT文は、文字を表示する命令です。
表示する文字はダブルクォーテーション(“)で囲みます。
PRINT “W”

ところでLOCATEとPRINTの間にコロン記号(:)が入っていますが、これはマルチステートメントといって、
1行に複数の命令を記述するときの記号です。
この先多用しますので覚えておいて下さい。

ここまでの解説で「どこ」に「なに」を表示するというのができるようになりました。
なお今回のゲームでは、このLOCATEとPRINTで全てのパーツを表示しています。

さて、座標の細かい話をする前に以下のプログラムを入力して下さい。
(覚えていますか?コマンドは大文字でも小文字でも、どちらで入力しても問題はありません)

これはもう定型文としてしか使用しませんので、そういうものと捉えて下さい。
一応それぞれのコマンドを以下に解説します。

WIDTH文は、画面の文字数を指定する命令です。
桁数(横文字数)は基本的に40か80、行数(縦文字数)は20か25を指定します。
WIDTH 桁数,行数

CONSOLE文は、もう1つの画面の制御文です。
最初の2つは何行目から何行スクロールするかを表し、次にファンクション表示スイッチ、次に白黒・カラー表示化のスイッチとなります。
なので入力したプログラムでは、0行目から25行スクロールして、ファンクション表示をOFF、カラー表示化となります。
CONSOLE スクロール開始行,スクロール行数,ファンクション表示スイッチ,カラー表示スイッチ

今回は40桁x25行で、ファンクション(画面下の文字)を消して、カラー表示に設定しました。

さて、画面の座標です。40桁x25行表示だと、以下のような座標になります。
(80桁の場合は横の最大数が39から79に、20行の場合は縦の最大数が24から19になります)

座標の原点は、左上角が(0,0)になります。右下角が(39,24)です。
…なんですが、実はカラー表示にすると1桁減って39桁となります。(なので左側が1桁空いています)
これはこのマシンのBASICの特性なので変えようがありません。
よってLOCATEで指定できるX座標は0〜38までとなります。

画面がカラー表示OKとなったので、表示する文字に色を付けてみましょう。
色は全部で8色ですが、0は黒なので背景が黒だと表示されません。
COLOR 色番号
 
サンプルプログラムはこちら↓ 入力前はNEWで前のプログラムを消しておきましょう。

ずいぶんと、カラフルになりましたね!

この章で、画面の桁・行の設定、ファンクション非表示、カラー表示化と、指定の位置に色を付けて文字を表示する方法がわかりました。
次の章ではゲーム画面を構築してみましょう。

解説:
実はCONSOLEを使っておくと入力が便利になります。
CONSOLEの3つ目の数値はファンクションキーの表示のON/OFF機能と説明しました。
機能的にSHIFTキーを押すとファンクションの表示が切り替わるので、次の入力を受け付けるまでタイムラグが発生します。
また実機上ではカーソルを左や下に移動させる時は、SHIFTキーを押しながら右と上なので、エミュ上のキー入力の
補完機能により、例えば左カーソルキーを押すとSHIFTキー+右カーソルキーを押したこととしています。
ですのでプログラムを始める前は、CONSOLE ,,0でファンクションキーを消しておいた方が、より快適に入力が可能になりますよ。
(カンマだけにすると数値を省略することができます)

ゲーム画面を描こう!

それではちゃっちゃとゲーム画面を描いてしまいましょう。

その前に補足です:
プログラムを入力してLISTで確認すると、間違って入れてしまった行があったりしませんか?
その場合、その行をまるまる消すには、その行番号を入力してRETURNキーを押して下さい。

↓以下のプログラムを入力して下さい。 前のプログラムが残っている場合はNEWで消してからですよ。
なおPRINT中で使っている文字の四角は、グラフキー+カンマキー(Mキーの横)で入力できます。

RUNで実行すると以下↓のような状態になったと思います。

あれ?なんか全部囲ってしまいました。ただし今は気にしないで大丈夫。
開発中にはよくある仕込みです。
それとOkと出てしまっていますが、それも気にしないで下さい。
単純に枠を書いてプログラムが終了したわけですから正常です。
それではここで出てきた新しい命令を解説しましょう。

PRINT CHR$(12)ですが、これも定型文です。画面全体をクリアします。そのまま使って下さい。
※詳しく言うと12という番号が画面全体を消すという文字コードで、その文字を表示するという意味です。
 そしてCHR$は、カッコで囲まれた文字コードを文字1文字に変換する命令です。
 画面を消す文字は入力できないのでこういう手法をとっています。

DEFINT A-Zですが、A-Zで始まる変数を整数型にするという意味で、BASICの実行速度を
多少でも上げる効果があります。これもほぼ定型文です。
※整数型というのは-32768 〜 +32767までの値しか使えませんが、桁数が少ないため計算が速くなります。

ここで解説:
変数とは値を入れておく入れ物です。
名前を付けることができて、1文字目がアルファベットA-Zで始まって、2文字目がA-Z及び0-9までの文字が使えます。
3文字目以降は付けることはできますが、ないものとして扱われます。
例をあげると、 A1 と A1Z は同じ変数として扱われますので、注意して下さい。
覚えておこう:変数は先頭の2文字までで区別される。

FORはちょっと詳しく説明します。
FOR 変数=開始 TO 終了 STEP 増減数
NEXT 変数
これは変数の値を開始から終了まで値を、増減数ずつ変化させながら、NEXTの間を繰り返すという命令です。
1110行を見てみるとX=2なので2から27まで、1130行の間を繰り返すことになります。
ですので、途中にあるLOCATE文のX座標が2,3,4,5…26,27と変わりながら実行されます。
STEPは増減数を指定するのですが、1ずつ上がるのであれば省略することができます。
なおネスト(入れ子)にすることも可能です。以下に例をあげます。
FOR Y=0 TO 23
FOR X=0 TO 39
LOCATE X,Y:PRINT “w”
NEXT X
NEXT Y
これで画面全体に”w”を描くことができます。なおNEXTは内側の方から変数を書きます。

この章で最初のゲーム画面を描くことができました。
次の章では何をするんでしょうか…。

そしてボールは飛んでいった…

さて枠ができたのでボールを飛ばしてみたいと思いませんか?

ではまずはボールの移動方向について定義しましょう。
ボールの移動する方向をX成分とY成分に分解すると下図のようになります。
(そこのアナタ!顔文字ではないですからねw)

そこで移動方向用の変数を次のように定義しました。
DX :X方向移動量、値は「-1」か「+1」とする
DY :Y方向移動量、値は「-1」か「+1」とする

次にボールの座標を定義します。
BX :X座標
BY :Y座標

ということで、1単位時間あたりのボールの移動式は以下のようになりますね。
BX=BX+DX
BY=BY+DY

この式を解説すると、=は代入を表しますので、BXとDYを足したものをBXに入れる(入れ直す)、となります。

ですので、最初にボールの座標と移動方向を各変数に設定して、ボールの移動する式を繰り返せば、
ボールは画面上を移動することになります。

で、追加するプログラムが以下です。ボールの丸はグラフキー+Gキーです。
行番号が飛んでいるので注意して下さい。

ここで新しい命令が出てきました。
GOTO文は、行番号で指定された行に処理が移動します。
GOTO 行番号
ここでは、2210行のボールの移動処理->2220行のボールの表示->そして2210行に戻る、をずっと繰り返すことになります。

さて、解説はここまでにして、実際に実行してみましょう。RUNで実行!

はい!突き抜けましたねw
そりゃそうです。当たり判定を入れていないんですから。
でも、設計通りに斜め方向へボールが表示されていきましたね。そこまでは成功です。
そうそう、プログラムは永久ループなので、STOPキー(JPキーボードだとESCキー)を押してプログラムを停止させて下さい。

今章の標語:プログラムの停止はSTOPキー。

さて、ここで1つ覚えて欲しい現象があります。
ボールが移動していって最下段にPRINTされたら画面がスクロールしましたね。
これはBASICの仕様と思ってもらって構いません。
で、プログラムをよく見てもらうとわかるんですが、壁の一番下は最下段の手前までしか描いていません。
もし、最下段まで表示したら画面全体がスクロールしてしまうので、その1つ手前までで表示をわざと止めています。
ですので、自分でゲーム等を作る場合は最下段に表示をしないよう、気を付けて下さい。
(これはあくまでもPRINT文を使った場合のみに起こる現象なので、スクロールしない方法もありますが、
今回はLOCATEとPRINTだけで表示を行うと決めたので、このようにしています。)

この章ではボールの移動方法について理解することができました。
次の章は少々やっかいです。がんばって。

リフレクション!

ボールが壁を突き抜けるという現象から脱却するために、当たり判定を付けたいのですが、
その前にボールは壁に当たったらどんな挙動をするのかを考えないといけません。

まず、床に反射する動きを考えてみましょう。以下の図を見て下さい。

仮想的に赤いラインで進んできていたボールが、白いブロックに当たって反射する動きです。
A、B、Cの順で状態が遷移するはずです。

さらに当たった瞬間を拡大してみましょう。

完全な球が平面に当たる場合は、赤い点の部分で当たるはずです。
ということは当たる直前の位置から、さらに移動する時、すぐ下にブロックがあれば反射するということになります。

ということで、今回は壁が4方向あるので、その全てをピックアップしてみましょう。

それぞれの壁には緑と紫の方向からボールが移動してきて反射します。
で、図をよくよく見てみると反射後はX成分の符号、またはY成分の符号が反転しているのがわかりますか?
(前章の移動方向の図を参考)

そうです、変数のDX、DYの符号を反転してあげれば反射処理になるんです。
符号の反転は、単純に「-1を掛ける」だけです。
DX=DX * -1 または DY=DY * -1 という処理を行うだけで反射ができるんですね。

では「壁に当たった」と判断するにはどうすれば良いか?ですが、これも上図から導くことができます。
正解を言うと「移動方向側の上下左右を確認すれば良い」になります。

移動方向側というのはDX、DYで表せられて、上下左右とはBX、BYの位置からです。
つまり、左右は(BX+DX、BY)であり、上下は(BX、BY+DY)です。

ここまでの条件をプログラムにしてみましょう。なお今回は、仮の当たり判定で組みます。
つまり以下の条件で判定します。
左右の壁:Xが2以下、または27以上だったら壁。
上下の壁:Yが0以下、または23以上だったら壁。
また今回も行番号が飛んでいるので入力にはご注意を。

いかがでしょうか?ボールがきちんと反射していますよね。

ここで新しい命令の説明とプログラムの説明をしましょう。

IF文は条件判断を行うコマンドです。
IF 条件 THEN 実行文 ELSE 実行文
IFの後に条件を記述し、条件に当てはまったらTHENの後の実行文を、当てはまらなかったらELSEの後の実行文を処理します。
ELSE以降は省略することが可能です。
2020行を見て下さい。ORで条件が連結されています。ORとは「または」と読み直すとわかりやすいです。
よって「Xが2以下またはXが27以上だったら(THEN)HTを1にする」と読み替えることができます。
2030行ではTHENの後が行番号になっています。THENの後は直接飛び先の行番号を記述することができます。

2090行にあるダッシュ(‘)ですが、これはこの記号の後は全てコメントとして扱って何もしないというコマンドです。
プログラムを作っている時に自分なりにわかりやすくするため、コメントを残したい時に使います。
なおREM というのも同じ意味となります。

2020行で座標を更新する前にボールを消しています。その後座標を更新してボールを表示しています。
座標を更新した後ではボールの跡が残ってしまうので、更新前に消します。

ところで、画面の最初にlist 2000-とあるのにはお気づきでしょうか?
LISTに行番号を指定するとその行またはマイナス記号を付けるとそれ以降全部を表示することができます。
またLIST 2000-2100とかにするとその中にあるプログラムだけを表示します。上手に活用して下さい。
それと、LISTが流れている時にESCキー(JPキーボードだとTAB)を押すと一時停止します。
こちらも活用できる技ですので、あわせてご紹介します。

さてきちんと反射しているとは思いますが、もう1つだけこのプログラムにおける反射のアルゴリズムの解説をします。
上下左右だけの単体の壁に当たった場合は良いのですが、以下のような時はどうでしょうか?
同時に2つの壁に当たった時です。

今回はこのプログラムで問題はありません。
要素的に左右の壁に当たったらX要素方向の処理を行い、上下の壁に当たったらY要素方向の処理を
それぞれで行えばきちんと逆方向に反射します。

…実はもう少しだけ反射に対する処理が必要なのですが、今の状態ではその処理をする必要がありません。
ですのでその話は次回以降で解説しますね。

疑問?:
Fという変数の処理が入っていますが、次回で意味を持ちます。
さてなんでしょうか?予想してみて下さい。

第二回まとめ

たくさん新しい命令が出てきたり、反射のアルゴリズムなどちょっとややこしい所もあったりしましたが、楽しんでいただけたでしょうか?
実際にモノが表示され、それが設計通りに動くと、ぐふふ、となりませんか?w
このプログラムをベースにいろいろ改造するのも楽しいはすです。(例えはボールを増やしてみるとか)
それでは第三回でお会いしましょう。
IF “第三回がアップ” THEN “閲覧する” ELSE “待機”

©HAL Laboratory, Inc.