サンプルプログラム7の改造
いよいよサンプルプログラム7ともこれでおわかれです。
時間をかけてサンプルがどう動いているのか見てきただけあって、今回はけっこうカンタンに話が終わるような気がします。
それだけみなさんもスキルアップしたということです。おめでとう!
前回いきなりサンプル7と関係ないビット演算の話が出てきておどろいたかもしれませんが、ちゃんと今回の話に使いますよ。
それもこれもふくめて、これまでの講座の総まとめです。
泣けるBGMなどをかけながら読んでみてください。

さて、サンプルプログラム7のつくり方はだいたい分かったけれど……

イヨイヨ、このロクでもねえプログラムをマシにカイゾウするってワケだな!

ソコまで言わんでもよかろうに……

いちどロードしなおしておこうか。
LOAD”SAMPLE7”
どこから手をつけたらいいのかな?

マッサキにおかしいトコロと言ったら、ゲームオーバーにならねェとこだろうな。

セイカクには、ゲームオーバーになるのは「敵が自機のいる21行目まで下りてきた時」ということになるかな。

チッ、コマカいやつだぜ!

どういうプログラムにするか、前もってハッキリとイメージしておくのはダイジじゃぞい。
まあ、思いつきでドンドン打ち込むのもひとつのダイゴミではあるが。

こまかく考えていくと、先頭の1匹が21行目についたタイミングがいいのかな。20行目のはじっこだとまだ早いって気がするし、何匹も21行目に乗っていると遅いかんじだもんね。

うむうむ、そういうコトじゃ。こういうのを「仕様を決める」と言うのじゃが、できるだけミノガシの少ない仕様を決められるのが良いプログラマーのジョウケンじゃぞい。

ムムム……アトは……そうだな、画面に「GAME OVER」って書かねェとな! そしてENDだ!

そうか、それはたしかにダイジだね。ちゃんとゲームオーバーだってわからないと。

まずは、そういう仕様で作ってみようか。まずサイショにすべきコトは……

もともとムダだった、自機のノコり表示をヤメようぜ! コメントアウトしとくか。
0028#. ’LOCATE 0,23
0027#. ’PRINT”Г:”;LEFT;

そのトオリじゃが、あいかわらずコトバがキビしいのう……。

ジッサイに敵が下におりる時のプログラムは……まずは
@DWルーチンかな。
0120#. @DW
0121#. EY(I)=EY(I)+1
0122#. IF EY(I)>20 THEN EY(I)=3
0123#. ED(I)=(ED(I)+1) AND 3
0124#. GOTO @EPUT

122行目では敵が画面の下から上にワープするように作ってあるけど、今回の改造ではココはいらないね。
0122#. ’IF EY(I)>20 THEN EY(I)=3
とりあえずコメントアウトしよう。

いや、せっかくIF EY(I)>20 THENなら、ソコでゲームオーバーにすりゃイイんじゃねェの?

オシイけど、ココではまだ敵が21行目に表示されていないんだ。さっき決めた仕様どおりに作るならハズレだね。

チッ、コマカいハナシはニガテだぜ! ウゴいた敵を書いてるのは、そのアトの
@EPUTルーチンだったか。
0137#. @EPUT
0138#. LOCATE EX(I),EY(I)
0139#. PRINT ”Е”
0140#. RETURN
どう見ても、139行目のアトにIF文を1行書けばイイはずだぜ!
0140#. IF EY(I)>20 THEN @GOVER
たいしてやるコトもなさそうだが、イチオウ新しく
ゲームオーバーサブルーチンに飛ばしといたぜ。

あとはムズカシイことは何もなさそうだね。
0142#. @GOVER
0143#. LOCATE 8,11
0144#. PRINT ”G A M E O V E R”
0145#. END

ウム。キチンとできておる。

しかし、やってみるとジミな気もするな。ドウセならこのぐらいは……
0142#. @GOVER
0143#. LOCATE PX,PY
0144#. COLOR 7
0145#. PRINT ”┷”
0146#. LOCATE 8,11
0147#. COLOR 13
0148#. PRINT ”G A M E O V E R”
0149#. END

うむうむ。いくら仕様を前もって決めていても、作ってみるともっとやりたいコトは出てくるモノじゃ。ためらわずアラタに作りはじめるココロもダイジじゃぞ。

言ってるコトがバラバラな気もするけど……

あと、ジブンでワケがワカらなくなる前に、ホドホドで止めておくキモチもやっぱりダイジじゃな。

どうしろってんだ!

どの考え方も同じくらい大切なものさ。うまくバランスをとってプログラムしていきたいね。
画面リセット
このコラムもこれがサイゴかもしれんと思うと……ワシじゃ、コラムのヌシことハカセじゃ。
さっきのプログラムでは
COLORを
15にモドさないウチに
ENDしておるから、その先にナニを打っても赤い字になるのう。
COLOR命令を何度も使うプログラムじゃと、いつも
COLOR 15で終われるとはかぎらん。そこで、ベンリな裏ワザを教えておくぞい。
- “Rボタン + 左ボタン + STARTボタン”
- こうDSiのボタンを押せば、画面がリセットされるのじゃ。
イマのところCOLOR 15:CLSと打つのとそう変わらんのでアリガタミがウスいかもしれんが、グラフィックやBG・スプライトに手を出すといよいよベンリになるコマンドじゃぞ。

次はどこを改造するのがいいかな。ゲームとしてちゃんとしてないのは……

そりゃ、敵のスピードが早すぎるコトだな! ゲームオーバーを作ってマスマスよくワカッたが、敵をオソくしねえとハナシにならねェぜ!

そう言えば、スピードをコントロールしてる部分がもうあったような……

! タシカに、オレとしたコトがワスレてたぜ!
0035#. @LOOP
0036#. GOSUB @MYSHIP
0037#. GOSUB @MYSHOT
0038#. GOSUB @ALIEN
0039#. GOSUB @SCORE
0040#. VSYNC(1)
0041#. GOTO @LOOP
メインループの中の
VSYNC(1)で1/60秒オソくしてたんだったな。じゃあ、コレをもっとオソくすりゃイイんじゃねェか?
0040#. VSYNC(20)

あれ? なんだか……
RUN

……あ、そうか。

し、シマッタ! 自機がオソいのは100歩ゆずっても、ショットがオソいのだけはガマンならねー!
というかコレ、ただゲームのテンポがユルくなったダケだな!

そういうコトだね。VSYNC()はその場でポーズするようなモノだから、ゲーム全体のスピードが変わってしまうんだ。

VSYNC()じゃなくて、敵だけが遅くなるような改造にしないとダメなんだね。

ムムム……自分やショットはウゴくが、敵はウゴかない……ん? そう考えるとアンガイよくあるパターンじゃねえか?

そう、敵を動かす部分をスキップすればいいってコトだね。
0117#. @EMOVE
0118#. IF ??? THEN @EPUT
0119#. ON ED(I) GOTO @RI,@DW,@LF,@DW
118行目を書きたして、ある条件のトキ以外は敵の場所を変えないことにしたよ。

ずっとスキップしっぱなしじゃ動かなくなっちゃうから、このIF文で「何回かに1回だけ動く」ようにすればいいってことか……。

だいたいハナシが見えてきたゼ。こうすりゃイイんだな!
0085#. ’--- シンリャクシャ
0086#. @ALIEN
0087#. ESTOP=ESTOP+1
まず敵をウゴかすオオモトのブブンに、変数
ESTOPをヨウイするぜ! コイツは敵を
止めるためのフラグだな。
0088#. IF ESTOP==9 THEN ESTOP=0
こうやって、10回に1回は
0にモドるようにしておくゼ! アトは、スキップするジョウケンを……
0119#. @EMOVE
0120#. IF ESTOP THEN @EPUT
IF ESTOP THEN、ツマリ
ESTOPがゼロじゃなければスキップする、ってコトにすればデキアガリじゃねえか!?

おっ、やったじゃないか! これで敵のスピードだけが10分の1になったね。

ワレながら、ジョウタツぶりがミゴトだぜ……。

あれ? そういえばこの10回に1回は0にもどるってパターンは……

どうやらオボエていたようじゃのう。ワンパク君のプログラムの、ドコを変えればいいかワカッたかの?

オレのプログラムのシュウセイがゼンテイかよ!

この88行目はやっぱりけずって……
0087#. ESTOP=ESTOP+1
0088#. IF ESTOP==9 THEN ESTOP=0

そしたら、数がフエるイッポウじゃねェか?

うーん、タシカにそうなんだけど。
0119#. IF FLOOR(ESTOP%9) THEN @EPUT
スキップの条件をこう書きかえれば、10回に1回だけ
FLOOR(ESTOP%9)の答が0になる……つまりスキップしないってコトになるよね。

「I=I+1でループするとき、FLOOR(I%N)と書くとIが『Nの倍数』になるたびゼロまでおり返しながら1増えていく」。前におぼえたホウソクだね。

やってるコトは同じじゃが、IF文がひとつ消えてコンピューターにやさしく、短いプログラムになったのう。
ESTOPの数はサイゴまで増えっぱなしじゃが、このゲームではメモリーのゲンカイまで増えるマエにゲームオーバーになるから、ソレもよかろう。

そこまでコウリツをモトめるその考えカタ、オレは気にくわねェな!

タシカに、ワンパク君のプログラムの方が初心者にはわかりやすいとも言えるわい。
どこまでプログラムにコウリツを求めるのがイイのか、それはプログラマーにとってエイエンのテーマじゃ。

どれがセイカイとも言えない、ってコトかな。ちなみにスキップする回数はちょっと変わるけど、こういう方法もあるよ。
0087#. ESTOP=(ESTOP+1) AND 7
#####. :
0119#. IF ESTOP THEN @EPUT
ビット演算のくわしいセツメイはもうはぶくけど、9回に1回だけ
ESTOPがゼロになってスキップしなくなるプログラムだね。
コンピューター的にはわり算よりビット演算の方が早いから、ボクはコレが
FLOOR()を使うよりもスキかなあ。

ケッキョク、プログラムするヤツのスキズキってコトか……。

セイカイがひとつとかぎらんのも、プログラムのおもしろさじゃな。プログラマー2人に合作させるとおたがいのビガクがぶつかって、見ていてオモシロいもんじゃよ。

……やじうま?

スピードが変わって、だいぶゲームらしくなってきたな!

敵が少なくなると、デタラメに撃っても当たらなくなるのがよくわかるね。だけどあんまりじっくり当てようとしていると、敵にせめこまれてゲームオーバーになっちゃう。ゲームにはこういうカケヒキがないとね。

なんだかハジメてホメられた気がするわい……。

こうなってくると、敵を全滅させた時に何もないのがさびしいね。ゲームクリア画面を作っておこうよ。

そうムズカシくないんじゃねェか? とりあえず敵の数をチェックするための変数がいるな。
0012#. ELEFT=EMAX
敵の最大数を決める変数
EMAXがもともとあったから、新しい
敵の
残り変数
ELEFTに使うことにするゼ!

敵が1匹やられるたびに、変数
ELEFTを1へらせばいいね。
0110#. ELEFT=ELEFT-1
あとはこの数がゼロになったら、
ゲームエンドでいいかな。
0111#. IF ELEFT==FALSE THEN @GEND

そこからは新しいサブルーチンになるね。
0157#. @GEND
0158#. LOCATE 11,11
0159#. PRINT ”シンリャク ミスイ”
0160#. END
こんなところかな?

サスガにサクサクいくようになったのう。
クリアしたシュンカン、はじめてゲームタイトルが出てそのイミがアキラカになる。ワシのノゾミどおりの、ハリウッド的クールなエンシュツじゃ。

そこまで考えてなかったけど……。

あっと、まだオワリじゃないよ。ひとつワスれてることがあったね。

そうか? トクにおかしいトコロはなさそうだが……
SCORE: 190

あっ! 最後の敵を撃った点が入ってないよ!

最後の敵が撃たれたらスグに@GENDに飛んでいるから、こうなっちゃうね。

じゃあ、
@GENDに飛んだサキですぐに点を入れればイイんじゃねェか?
0157#. @GEND
0158#. GOSUB @SCORE

ず……ずいぶんストレートな方法でカイケツしてきたね。

@SCOREに行って10点プラスして帰ってくるワケじゃな。10点以上の敵を倒してクリアしたトキはどうする、というモンダイはあるが……そもそも10点以上の敵がいないので、マチガイなくこれでカイケツはしておるな。

いいの? ハカセにしてはアッサリしてるけど。

何点の敵がアイテでもOKなプログラムを組むのがリソウではあるんじゃが……、ショクンならフラグをうまく使えばスグにできるじゃろうしな。10点以上の敵を出すヨテイもないイマは、これでよかろう。

(さっき点の入れワスれに気がつかなかったコトを、ゴマカそうとしてるんじゃねェか……?)

あとは、ショットを画面タッチからAボタンに切り替えれば、ボクらのキボウもだいたいかなったことになるかな。

ショットは70行目で入力チェックしていたんだっけ。
0070#. IF TCHST==FALSE THEN @MSSKIP
システム変数
TCHSTが
FALSEだったら(タッチされてなかったら)ショットをスキップする、っていうやり方だね。

そのままBUTTON()に置きかえればすむコトじゃねェか! ……ン?
この前にB=BUTTON()してるから、IF B AND 16と書けばAボタンを押してるのはワカるが……

そのままそう書くと、THENの後のイミがちがっちゃうね。
スキップするのは変えたくないから、ここには「IF (Aボタンが押されていない) THEN @MSSKIP」と書きたいけど……。

えーと、ビット演算のときにおぼえたけど、
BUTTON()で変数に入る数は、2進数に直すと第0ビットから1ケタずつ、スイッチになってるんだったよね。
十字ボタン↑ | 1 | 000001 |
十字ボタン↓ | 2 | 000010 |
十字ボタン← | 4 | 000100 |
十字ボタン→ | 8 | 001000 |
Aボタン | 16 | 010000 |
Bボタン | 32 | 100000 |
: | : | : |

たとえば「十字ボタン→」と「Aボタン」が同時押しされていれば、変数に入る数は2進数では
011000になるね。
これに
AND 16すると……
011000
AND 010000
= 010000
Aボタンの第4ビットだけが立っているかどうかわかる、というのがおさらいになるね。

オサライかよ、オレのキライなナガレだぜ!

うーん……そして、Aボタンが押されていない時に
AND 16すると……
001000
AND 010000
= 000000
ほかのボタンを押していても、答はゼロになるわけだね。あたりまえだけど……

オ、オイ! ソレじゃねえか!?

え?

! (……ワンパク君! キミが……)

AND 16すりゃ、Aボタンを押してないトキにはゼッタイ
0になるんだろ?
イマまで使ったことのねェやり方だけどよォ、それなら「
IF (Aボタンが押されていない)
THEN @MSSKIP」ってのも書けそうじゃねェか!
0070#. IF B AND 16==FALSE THEN @MSSKIP
……ム。ヘンな書き方になった気もするが……
RUN

チクショウ! 合ってると思ったんだが……ウマく動いてねえ!

いやいや、考え方はバッチリだよ。

ナニ?

その書き方だと、「
B=TRUE」
AND「
16==FALSE」のように読めちゃうから、おかしくなるんだね。カッコでかこんで、こうして書けばいいんだよ。
0070#. IF (B AND 16)==FALSE THEN @MSSKIP

ホントだ! これならうまく動くよ!

ワンパク君……イージーミスでつまずいたものの、あれだけニガテだったビット演算の考え方をキチンとリカイしたようじゃのう。ワシはうれしいぞい。

ダテにあのメンドクセェ講座をくぐり抜けてきたワケじゃねえぜ!

おぼえたコトは、なんでもムダにはならないってコトだね。
ビット演算にかぎらず、このBASIC講座で勉強したことは、イガイなところで役に立ったり、応用しだいでもっとイロイロな使いみちがあるハズさ。

そういうコトじゃな。読者のショクンも、このサンプルをさらに改造するコトから始めてみてはどうかな?
これまでの講座でおぼえた命令を組み合わせると、イガイにやりたいコトができたりするものじゃ。

たしかに、まだ改造したいポイントはいっぱいあるね。敵の種類をふやしてみたいし、プレイヤーが1機でおわりじゃなくてもいいよね。

もっとカラフルにするのもよさそうじゃな。敵がやられたトキにバクハツパターンを出すなどもいいじゃろう。
こういう見た目のエンシュツはイガイに考えるトコロが多く、うまくいったトキのジュウジツ感も大きいのでオススメじゃぞ。

やりたいコトに手が届かない時は、説明書をながめてみるのもいいかもね。
ムズカシそうだけど、ここまで読んだ今なら、何が書いてあるのかカナリわかるようになってるハズだよ。

……テメーら! サイゴだけマジメなコトでまとめて、さもキョウイク的なナイヨウだったってカオしてんじゃねえぞ!
- 画面リセット
- “Rボタン + 左ボタン + STARTボタン”を押せば、画面がリセットされます。
- まとめ方
- 最後のほうで、みんないい子になって教育的なことでまとめれば、まるでいい講座だったように思い込めるものです。