2018年11月19日

プチコンゲームプログラミング講座~第一回「すごく簡単なゲームを打ち込んでみよう」

文 プチ太郎 氏
=-=-=-=-=-=-=-=-=-=-
 前回は自己紹介程度だったので、今回からゲームと言えるプログラムを掲載し、それを解説・学習していきます。

 「命令文の入力方法も知らない人向け」から、「テキストエディタぐらいや簡単な命令文は使えるが、命令文を組み合わせてプログラムを完成させるまでは無理」まで、どれくらいの学習度の人を対象にするのか、なかなか迷うところなんですが…このブログの他の講座を見るとだいたい後者ぐらいなので、この連載も後者にあわせます。

 「最低限簡単なプログラムで、最低限何度か遊びたくなるゲームは何だ?」と聞かれたら、いろんな回答が多いかしら? 私は今回ここで、2作品を挙げようと思ったのですが…実は力が入り過ぎて、前回やここのブログの他の内容に比べ、大幅に容量が増えてしまいました(^^;どうしようか悩んだのですが、一回目から量が多いと引かれそうなので、今回は1作品のみとしました。

 色は白黒のみ、使用キャラもスプライトは無しで文字グラフィックだけ、サウンドも最小限です。この辺は次回以降、機会を見てさらに加えた演出を説明予定です。

教材プログラム 1-1 「スクロールスキーゲーム」(ファイル名「KOZA01-1」)

PGP01_1.jpg

★ ゲームの概要 ★

 皆さんはコンピュータに表示される文字が多すぎて、下まで行ききったら、どうなると思いますか? 現代のコンピュータプログラムはそこまでちゃんと考えているので、「絶対文字がはみ出さない」か「画面が上下左右にスクロールする」どっちかだと思います。

 昔のコンピュータ、特にホビーマイコンや高級言語では「ラリーX」や「ドラクエ」のように画面をスクロールさせる事が難しく、スクロールするゲームは、機械語を使わねばなりませんでした。

 ところが文字が下に行ってしまうと、今でも多くのパソコンの機能やアプリは、強制スクロールします。これをうまく使って下にスクロールし続けながら、障害物を避けるゲームというのが、昔から今でも結構存在します。「最低限何度か遊びたくなるゲーム」の中では、もっとも短い行数と言えましょう。

★ ゲームの内容 ★

 一口に一方向スクロールゲームと言っても、障害物を避けるもの、目標物に当てると得点になるもの、両側に壁が出るもの、横に進むものなど、いろいろあります。今回は前述通り、一番簡単に作れる内容でかためました。

1.画面中央の人型が、あなたの操るプレイヤーキャラクターです。十字ボタンで左右に動かして、迫ってくるゲートの中(「アンダーバー」と呼ばれる下線"_"の部分)を通ってください。通ると点数が入ります。
2.10点ごとにスピードが上がります。
3.ゲートの横の四角"■"にぶつかったらゲームオーバーです。Yを押すとまたゲームができますが、Xを押すとプログラムを終了します(Y=Yes、X=バツ、と覚えて下さい)

★ プログラムの説明 ★

PGP01_1B.jpg

 "@"から始まる文字は「ラベル」(Label)と言って、GOTOやGOSUBでジャンプ先、またはデータの読み込み先を指定すると、そのラベルのすぐ下からプログラム実行やデータ読み込みを開始します。言語によっては"*"を使うものもあります。

★2行目
 ACLSは"All CLear Screen"の略で、訳としては「画面要素全削除」となります。プチコンを構成する画面要素のほとんどがリセットされます。スプライトなどもリセットされてしまうので、一般にプログラムの一番最初、および終了して元の一般的な画面に戻る時(このプログラムでは22行目)だけ書きます。だが今回は簡単なゲームなので、リプレイのたびにACLSをしても問題ないので、リプレイ時には一番最初にGOTOしています。

 ACLSの後は、ゲームで使う変数の初期設定です。一般的なゲームの場合、実行後の一回だけ設定、面クリアごとに設定など、設定のタイミングが何種類かありますが、今回は前述通り簡単なゲームなので、全て初期設定だけです。一通り説明しましょう。

 ・X - プレイヤーキャラクターの初期位置。プチコン3号の上画面は50字幅なので、左端が0で右端が49。つまり24は真ん中です。このゲームではキャラの高さがずっと同じなので、縦位置を表す"Y"は使っていません。
 ・S - "Score"のS、つまりプレイヤーが取得したスコア。
 ・S2 - スコアが上がるたびに、レベルアップする基準。
 ・W - ゲーム全体の待ち時間。これもレベルアップすると少なく、つまり速くなります。

★4行目、15行目
 @LOOPは名前通りメインループです。ゲームに何か変化があってGOTOで外に飛び出さない限り、15行目の"GOTO @LOOP"で、また7行目に戻ります。

★5~6行目
 BUTTON()は後ろにカッコが付いていますが、プチコンでは関数は全て、後ろにカッコが付いています。これはDSのボタンが現在押されているかを返す関数で、何も押さないとゼロを返すが、どこかのボタンが何個押すかで、返す数値が変わります。返す数値の中身については、また次回以降に詳しく解説します。

 頭にシャープ(#)を付けた文字は、ツイッターのハッシュタグ…でわなくてwプチコン3号のバージョンアップで追加された「定数リテラル」と言います。定数という通り、一つの名前に必ず同じ数字しか入っていないのですが、名前を見ればどういう存在かわかるので、リストが少し読みやすくなります。「IF BUTTON()==4」より「IF BUTTON()==#LEFT」のほうが、「左」だとわかりますね? つまりこの行は

・5行目「もしボタンが左に押され、かつキャラの座標がゼロ未満であれば、座標変数Xを一歩左に動かせ」
・6行目「もしボタンが右に押され、かつキャラの座標が49を超えないなら、座標変数Xを一歩右に動かせ」

 です。第0回の教材プログラム0-2(ファイル名「KOZA00-2」)とよく似ていますね。

★7~8行目
 LOCATEは文字表示の場所を指定する命令で、ドラマや映画の「ロケ」とい同じ語源です。昔は"CURSOR"と書くBASICもありましたが、マイクロソフトBASICが出てきてからは、ほとんどLOCATEです。

 それから、"?"という記述がありますね。実はこれ、文字を表示するPRINT命令が面倒で、省略して書けるようにしたものです。普通のBASICは"?"と入力しても、PRINTに自動変換されていたのですが、初代プチコンではこれをうっかり忘れてしまい、"?"とPRINTが同じ働きをする別々の命令として存在しています。その"?"で、文字キャラクタの中からキャラクタグラフィックの、「上向き人形」を出しています。これは1978年に発売されたMZ-80K/Cで登場した文字キャラで、使いやすいため、多くのゲームにも使われました。

 BEEPは一番簡単なサウンド「ブッ」を出して、全く音のないゲームの遊びにくさをフォローしています。

 RND関数はRANDOMの略、つまり乱数を返します。現代では「最少はゼロ~最大はカッコ内の数マイナス1」がランダムで出るので、RND(45)は横座標の0~44が出るという事ですね。画面座標は49まであるので、45~49文字目には出さないか?と思いますが、それは"?"で書いている、”■___■”を書く事で、49文字目まで使っています。ここで一番下の29行目に表示する文字列に「改行しない」という意味の”;”(セミコロン。命令文の間の”:”はコロン)を書いていないので、何が何でもここで画面がスクロールします。

 なお四角い"■"はプチコンに二種類あり、わかりにくいのですが、ここでは小さめで隙間の有るほう(キーボードでハートマークを押して、画面上部の”(”のあたり)を入力しています。大きめで隙間の無いほう(画面右下の”.”のあたり)ではありません。8行目と13行目両方で同じ文字を入力すればいいが、それぞれ違うとゲーム進行がおかしくなるので、注意して下さい。

★9行目
 9~12行目は微妙に違う処理を二つ並行しているので、判らない人には判りにくくなるかも知れません(簡単なゲームでも、そうしないとゲームが完成出来ない部分があります!)CHKCHR関数は「カッコ内の座標にある文字の文字コードを返す」、CHR$関数は「カッコ内の文字コードに文字を返す」。これが文字変数"C$"に入ります。本当はCHR$を使わずに「C=CHKCHR(X,10)」のほうが簡単なのですが、そうすると条件判断が「IF C==数字 THEN…」で初心者に読みにくいので、わざとCHR$を挟みました。

★10行目、12行目
 9行目のC$が”_”、つまりゲートだったら、ポイントを通過したという事で、得点の変数Sに一つ追加しています。得点はその時取っても取らなくても、12行目で表示し続けています。これは8行目で強制スクロールするので、ここで再度書かないと、得点が見えなくなるからです。

★11行目、14行目
 「現在の得点Sが次のレベルアップ基準S2に並んだなら」、待ち時間Wを1つ減らし、レベルアップのS2を10増やしています。ただしそのまま続けると、Wがゼロになったら待ち時間が無くなってメチャクチャ速くなり、-1だと文法エラーで止まってしまうので、最初のIFの時に「… AND W>0」も入れて、Wは絶対1以下には減らないようにしています。変数Wによる時間待ちは14行目。待ち時間は原則として一番最後に書きます。

★13行目、17行目~
 9行目とほぼ同じ処理で、C$が”■”、つまり柱だったらゲームオーバー。IF文の後の処理は、そんなに数が多くなかったり(今回はここ以外のIFはみんなそうしている)、ENDIF(今回は使っていない)でまとめられるならそこで書きますが、ここは量が多いのと、その後@LOOPには戻らないので、@GAMEOVERに飛ばしています。

PGP01_1C.jpg

★18行目~19行目
 ここはまた文字表示ですね。

★20行目
 BEEP 108はプチコン3号から追加された、通称「大爆発」で、結構凄い音がします。よく使うBEEP番号として、108は覚えておいて損はないです。

 WAIT 60ですが、1fpsは60分の1秒、つまりちょうど1秒待ちます。これは画面演出をゆっくり見せたいという理由もありますが、WAITを入れておかないと、遊んでいる人がボタンを押したままで、すぐ次の画面に行っちゃって、「え?今どうなったの?」と迷う事があるからです(ミーバースのプチコン3号コミュを読んでいたのですが、初めての人は結構ハマるミスのようでした)

★21行目~
 REPEATとUNTILは、FOR文(今回出てきませんでしたね。詳しくは後日!)やIF文の変形みたいなもので、UNTILの後の条件が「YES」になるまで、繰り返し処理をするというものです。つまり「IF 条件 THEN その後の処理…」と「REPEAT:途中の処理:UNTIL 条件:その後の処理…」は、同じようなものです。

 変数Bで何をやっているかは、もう判りますね。押されたボタンが「#X」ならACLSして、ENDでプログラム終了。「#Y」ならまた@INITからやり直しです。

★ 最後に ★

 次回からは、徐々に複雑にしたいろいろなゲームを挙げて、プログラムのスキルを上げて行きます。また「こんなジャンルのゲームを扱ってほしい!」というリクエストもお待ちしています。ANDとOR、BEEPとBGMPLAYなど、今回簡単な解説で済ませた命令や関数については、後日また解説予定です。

(第二回につづく)

★今回の教材プログラムがうまく打ち込めなかった方のために、同じ教材プログラムを、サーバにアップしてあります。必要な方はサーバからダウンロードして、どこが間違っているかなどを、見比べてみて下さい。

公開キー  :XK2NEDC1(連載が進んで新しい教材プログラムが追加されると、公開キーも変わります。この公開キーでダウンロード出来ない場合は、連載の一番新しい回の公開キーをご利用下さい)
プロジェクト:KOZA
ファイル名 :上の教材プログラムの見出しをご覧下さい。

=-=-=-=-=-=-=-=-=-=-

次の更新は、11月22日。『ゲームむかしがたり『チャンピオンシップ・ロードランナー』』の予定です。お楽しみに!