プチコンmkII

プチコンmkII 初心者講座

サンプルプログラム7 (その1)

プログラマーからひとこと

いよいよサンプルプログラム7、この講座ではこれが最後のサンプルです。
サンプルプログラム5や6はやってませんけど……。
うーん、エピソード1〜3を飛ばしてエピソード4からストーリーが始まる的な?
いや、そういうものでもないですね。

サンプル5と6は、「グラフィック面」や「BG面」といった、これまでとはだいぶ違うものの話になるので、この講座ではいったんおいておきます。
新しくおぼえる命令がドーンと出てくるので、そういうのって思わずくじけちゃいそうじゃないですか。

それよりは先にスパッとアクションゲームを作ってしまいましょう。
そうです、そういえばサンプルプログラム7はゲームです。それもアクションゲームです。
いよいよって感じですね。
だいたいは、これまでにおぼえたことの組み合わせで、できるようになっています。

と言っても、応用そしてまた応用なのはたしかなので、何回にもわけてじっくりやっていくことにしましょう。
どんなゲームなのか、とりあえず見てみましょう。

サンプルを遊んでみよう

ハカセ「いよいよクライマックスというカンジじゃのう。これは今のショクンにピッタリのサンプルプログラムじゃろう。
LOAD”SAMPLE7”
OK
RUN
画面
インテリ「自機を左右に動かしながら、上からせまる敵をショットで打つゲームだね。
神崎「十字ボタン左右で移動。画面タッチでショットっていうのはめずらしいね。
ワンパク「いや……ちょっと待て、コレおかしいぞ! どうやっても負けにならねーじゃねェか!
ハカセ「じゃから、タイトルが「侵略未遂しんりゃくみすい」となっとるじゃろ。カレらは、最後までシンリャクできなかったのじゃよ。カナしい話じゃな。
ワンパク「いやそうじゃねェだろ! ナンのための残機ヒョウジだよ! だいたい敵をゼンブ倒しても特にナニも起きねー!
ハカセ「ウム……、コレはそもそもユーザーショクンのチカラで、未完成のプログラムを完成させようというシュシなのじゃ……が……ちょっとムリがあったじゃろうか。
神崎「まあ、そういうコトなら……いいの……かな?
インテリ「そういうことにしておこうよ。今のところ気になるポイントは、
・敵にせめ込まれてもダメージがない
・敵をゼンブ倒しても終わらない
この2つかな?
ワンパク「・敵のスピードが早すぎる
ってのもモンダイだぜ。
神崎「・Aボタンでショットにならない
のもやっぱりやりづらいよね。
ハカセ「ワシが言うのもなんじゃが、テキカクなシテキじゃな。
ホカにもプラスアルファのためにいくつか変数をしこんでおるんじゃが……
ワンパク「それはイイや、コレ以上ふやすとタイヘンそうだしな!
ハカセ「ワシが言うコトでないかもしれんが、テキカクじゃのう……。

再現をはじめてみよう

インテリ「プログラムを改造するには、まずプログラムをリカイした方がいいよね。せっかく総まとめのプログラムなんだから、イチから自分で作るつもりでやってみようか!
神崎「カンタンそうに言うなあ……。
インテリ「ムズカシく見えても、だいたいはこれまでのおさらいでデキるプログラムだよ。
たとえば、プログラムのサイショに何をすればいいのかはもうわかるよね。
ワンパク「そこはイマまでのサンプルと同じパターンでイケるだろうな。
0001#. ’┌──────────┐
0002#. ’│SAMPLE7   │
0003#. ’│ シンリャクミスイ │
0004#. ’└──────────┘
0005#. VISIBLE 1,1,0,0,0,0
0006#. CLS:COLOR 0
0007#. CLEAR
だいたいこんなモンか。本当はこのアトにDIM命令がくるんだろうが……。
0008#. DIM ???
配列変数のヨテイが立ってないから、トクに思いつかねェぜ!
インテリ「そのあたりは後で出てくるだろうから、今はまだいいかな。
REMのを行のはじめに入れて、メモとして残しておこうか。
0008#. ’DIM ???
ハカセ「いわゆる「コメントアウト」じゃな。プログラムを組みながらなら、こういうコメントの使い方もユウコウじゃぞ。

動かしてみよう

ワンパク「ウーム……とりあえずプレイヤー機を出してはみたが……
0010#. ’---
0011#. LOCATE 10,21:PRINT”Г”;
0012#. LOCATE 0,22
0013#. PRINT”────────────────────────────────”;
神崎「サンプルプログラム1のころにおぼえたコトだね。
インテリ「このプレイヤーを動かすプログラムがいるだろうね。いまのうちにメインループを作っておこう。
0020#. ’---
0021#. @LOOP
0022#.  GOSUB @MYSHIP
0023#. GOTO @LOOP
神崎「このラベル@MYSHIP自機マイ・シップ)で、プレイヤーを動かすサブルーチンを作るんだね。
ワンパク「サンプル3の方法で左右に動かすなら、こんなカンジだろ?
0025#. ’--- シ゛フ゛ン
0026#. @MYSHIP
0027#. B=BUTTON()
0028#. IF B AND 4 THEN ???
0029#. IF B AND 8 THEN ???
0030#. RETURN
だが、わからねえ! このIF文をどうすりゃ、プレイヤーが動くんだ?
インテリ「そういえば、まだキャラクターが動くタイプのプログラムはやったことがなかったね。少しじっくり作ってみようか。
0011#. LOCATE 10,21:PRINT”Г”;
まずはこの行に注目かな。
ワンパク「イチバンはじめのトコロじゃねェか! オレのヤリ方にモンクでもあるってのかよ!
インテリ「このLOCATEの数字を変えると、プレイヤー機のバショも変わるのはなんとなくイメージできるかな?
神崎「まあ、それくらいなら。
たとえばLOCATE 11,21:PRINT”Г”;と書けばもう1文字ぶん右に行くよね。
ワンパク「ソレと押されたボタンを組み合わせるのか……ツマリ、BUTTON()が押されたらLOCATEの数字を変える……? しかしLOCATEの数字を変えるには……
神崎「あ、変数を使うんだ!
ワンパク「! ……「数」が「変」わるから「変数」。そういうコトか……!
インテリ「そうマチガってるワケでもないかな。数字がたびたび変わるようなトコロは、変数で作っておくとベンリだね。
神崎「ということは、この行も……?
0011#. LOCATE 10,21:PRINT”Г”;
インテリ「こんな感じがいいんじゃないかな。
0011#. PX=10:PY=21
0012#. LOCATE PX,PY:PRINT”Г”;
変数の名前に使ったプレイヤーPlayerのP。はヨコ方向・タテ方向のイミだよ。
ハカセ「数学で「座標」のヨコ方向に「x」、タテ方向に「y」を使うコトがモトモトのイミかのう。コンピューターのセカイでもヨコといえばX、タテといえばY、というコトが多いのじゃ。
ワンパク「リクツはワカッてきたぜ。ボタンのあたりは、こうすりゃイイんだな?
0025#. ’--- シ゛フ゛ン
0026#. @MYSHIP
0027#. B=BUTTON()
0028#. IF B AND 4 THEN PX=PX-1
0029#. IF B AND 8 THEN PX=PX+1
0030#. LOCATE PX,PY:PRINT”Г”;
0031#. RETURN
左ボタンを押せばPXから1引いて、右ボタンを押せばPXに1足すってワケだ。そのアトにLOCATEしてPRINTすればバッチリだぜ!
ハカセ「さて、どうかのう? ためしにRUNしてみるかの。
画面
ワンパク「ウ、ウォオー! ナンだコリャアー!
インテリ「アイデアはまちがってなかったけど、いくつかダイジなところが抜けていたね。
まず、B=BUTTON()から戻ってくるまでのループが早すぎるってこと。ボタンをチョンと押しただけで、ものすごいスピードで何度も押したことになってるんだな。
神崎「そういえばサンプルプログラム3でも、そんなコトがあったね。
インテリ「となると、思い出すこともあるんじゃないかな?
0021#. @LOOP
0022#.  GOSUB @MYSHIP
0023#.  VSYNC 1
0024#. GOTO @LOOP
メインループの中にVSYNC命令をふやしたよ。
神崎「60分の1秒だけプログラムの動きを止めるんだったね。早すぎるループをわざと遅らせるのはワカるけど……60分の1秒って、そんなあっと言う間でいいの?
インテリ「そのくらいでも、アクションゲームならイガイとちょうど良かったりするんだよ。ものたりなければ、増やせばすむコトだしね。
ワンパク「ナルホドな。とにかくモンダイはカイケツだぜ。RUN
画面
ワンパク「カイケツしきってねェー!

動かし方のコツを学ぼう

ハカセ「ナニがおきておるのか、23行目をVSYNC 20ぐらいに変えて見るとハッキリするじゃろう。
こういう「重しウェイト」をかけるのは、テストにはユウコウじゃぞい。
ワンパク「な……ナンとなくはワカッたな。ヨコに動かすと、プレイヤー機が分身するみたいに増えていっちまうんだ。
インテリ「いちど画面にPRINTした字は、消さなきゃずっとそこに残っちゃうのさ。
神崎「言われてみれば当たり前だけど……じゃあどうやって消せばいいの?
インテリ「それはカンタンさ。” ”つまりスペースを同じ場所にPRINTすれば、Гはなくなるってワケだね。
ワンパク「消すっつーか、上書きするっつーか、だな。
このプログラムだと、モトの場所にスペースを書けばイイんだから……ン? ブツブツ……ボタンが押されたらもうPXを変えてるワケで……モトの場所を消さないとイケねェんだけど、ボタンを押してないのに消したらマズいワケで……
イマイチわかんねェぞ!
インテリ「これは、もっとプログラムを書き足さないといけないね。
0025#. ’--- シ゛フ゛ン
0026#. @MYSHIP
0027#. B=BUTTON():VX=0
0028#. IF B AND 4 THEN VX=-1
0029#. IF B AND 8 THEN VX=1
0030#. LOCATE PX,PY:PRINT” ”
0031#. PX=PX+VX
0032#. LOCATE PX,PY:PRINT”Г”;
0033#. RETURN
わかるかな? クッションになる変数VXを新しく作ったよ。
神崎「ええと、ふだん変数VXで、ボタンを押したときだけ-1になるんだね。
ワンパク「変数PXはまだ変わってねェから、まずスペースで消して……あらためてPXVXを合わせてからLOCATEしなおしてГPRINTするってワケか!
ワレながら、英語の多いコトバをしゃべっちまったぜ!
ハカセ「英語ついでに言うと、変数VXの「V」は「動く方向と量」という意味の「ベクターVector」のコトじゃな。プログラムではよく使われるコトバじゃが、広義のベクトルと違って……
神崎「ちょ、ちょっと待って! センモン的なハナシはいいんじゃないかな。
それより、ボタンが押されてない時にもいったんスペースで消して、同じ場所にもういちどГを書いているよね。これはいいの?
インテリ「RUNしてみるとわかるけど、すごいスピードで消しては書いてるから、そう気にはならないね。
でも、それがベストかというとビミョウかな。こう書くのが正しいのかもね。
0025#. ’--- シ゛フ゛ン
0026#. @MYSHIP
0027#. B=BUTTON():VX=0
0028#. IF B AND 4 THEN VX=-1
0029#. IF B AND 8 THEN VX=1
0030#. IF VX==0 THEN @NOTMOVE
0031#. LOCATE PX,PY:PRINT” ”
0032#. PX=PX+VX
0033#. LOCATE PX,PY:PRINT”Г”;
0034#. ’---
0035#. @NOTMOVE
0036#. RETURN
ボタンが押されていないときは、イッキにラベル@NOTMOVE動かないNOT MOVE)まで飛んで、プレイヤー機をPRINTし直さないことにしたよ。
ワンパク「コレで動きはバッチリってコトだな。RUNしてみるゼ!
画面
ワンパク「チ、チキショー!
画面のハジまで動かしたら、オカシなコトになっちまったぜ!
神崎「それは、変数PXが画面を飛びこしちゃったのがゲンインかな?
インテリ「PXのときに-1しちゃったり、PX31のときに+1しちゃったり、だね。
ワンパク「テメーら、もっとわかりやすいコトバでしゃべりヤガレー! 画面のハジまで行ったら、それよりムコウに動かさないようにすればいいだけじゃねえか!
インテリ「これはワンパク君の言うとおりだね。ГPRINTする前に、IF文を2行用意しておこうか。
0032#. PX=PX+VX
0033#. IF PX<0 THEN PX=0
0034#. IF PX>31 THEN PX=31
0035#. LOCATE PX,PY:PRINT”Г”;
神崎「これでプレイヤーの動きはモンダイなくなったね。
ワンパク「コレはコレで、動いてねェプレイヤー機を消しては書いちまってるが……、モトのサンプルプログラムがこうだからシカタねェのか?
ハカセ「し、しもうたァ━━ッ!
インテリ「ま、まあそのあたりはコンゴのカダイとして……。
いったん、ココまでのプログラムをまとめておこう。
どういうイミなのか考えながらジッサイに打ち込んでみると、もっとよくワカると思うよ! モニタの前のみんなもやってみてね!
プログラムリストを表示(※表示ボタンがあるのはWeb版に限られます。別ページのリストをごらんください)

今回のまとめ

キャラクターを動かすには
たとえばLOCATEの位置を変数にして、BUTTON()の入力に合わせてIF文で変数を足したり引いたりすると、動いて見えます。
動く前にいた場所に、空白スペースを上書きして消してやると自然に見えそうですね。
LOCATEする場所が画面をはみださないように注意!
VSYNC命令とアクションゲームの関係
プログラムを一時停止するVSYNC命令で、スピードを落とせます。早すぎて操作が追いつかない時にはとてもよく使いますね。