プチコンmkII

プチコンmkII 初心者講座

サンプルプログラム7の改造

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

いよいよサンプルプログラム7ともこれでおわかれです。

時間をかけてサンプルがどう動いているのか見てきただけあって、今回はけっこうカンタンに話が終わるような気がします。
それだけみなさんもスキルアップしたということです。おめでとう!

前回いきなりサンプル7と関係ないビット演算の話が出てきておどろいたかもしれませんが、ちゃんと今回の話に使いますよ。
それもこれもふくめて、これまでの講座の総まとめです。
泣けるBGMなどをかけながら読んでみてください。

ゲームオーバーを作ってみよう

インテリ「さて、サンプルプログラム7のつくり方はだいたい分かったけれど……
ワンパク「イヨイヨ、このロクでもねえプログラムをマシにカイゾウするってワケだな!
ハカセ「ソコまで言わんでもよかろうに……
神崎「いちどロードしなおしておこうか。
LOAD”SAMPLE7”
どこから手をつけたらいいのかな?
ワンパク「マッサキにおかしいトコロと言ったら、ゲームオーバーにならねェとこだろうな。
インテリ「セイカクには、ゲームオーバーになるのは「敵が自機のいる21行目まで下りてきた時」ということになるかな。
ワンパク「チッ、コマカいやつだぜ!
ハカセ「どういうプログラムにするか、前もってハッキリとイメージしておくのはダイジじゃぞい。
まあ、思いつきでドンドン打ち込むのもひとつのダイゴミではあるが。
神崎「こまかく考えていくと、先頭の1匹が21行目についたタイミングがいいのかな。20行目のはじっこだとまだ早いって気がするし、何匹も21行目に乗っていると遅いかんじだもんね。
ハカセ「うむうむ、そういうコトじゃ。こういうのを「仕様しようを決める」と言うのじゃが、できるだけミノガシの少ない仕様を決められるのが良いプログラマーのジョウケンじゃぞい。
ワンパク「ムムム……アトは……そうだな、画面に「GAME OVERゲームオーバー」って書かねェとな! そしてENDだ!
神崎「そうか、それはたしかにダイジだね。ちゃんとゲームオーバーだってわからないと。
インテリ「まずは、そういう仕様で作ってみようか。まずサイショにすべきコトは……
ワンパク「もともとムダだった、自機のノコり表示をヤメようぜ! コメントアウトしとくか。
0028#. ’LOCATE 0,23
0027#. ’PRINT”Г:”;LEFT;
ハカセ「そのトオリじゃが、あいかわらずコトバがキビしいのう……。
神崎「プログラムの中で敵が21行目におりてくるとすると……@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
たいしてやるコトもなさそうだが、イチオウ新しくゲームオーバーGame OVERサブルーチンに飛ばしといたぜ。
神崎「あとはムズカシイことは何もなさそうだね。
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
画面
ハカセ「うむうむ。いくら仕様を前もって決めていても、作ってみるともっとやりたいコトは出てくるモノじゃ。ためらわず新しく作りはじめる心もダイジじゃぞ。
神崎「言ってるコトがバラバラな気もするけど……
ハカセ「あと、自分でワケがワカらなくなる前に、ホドホドで止めておく心もやっぱりダイジじゃな。
ワンパク「どうしろってんだ!
インテリ「どの考え方も同じくらい大切なものさ。うまくバランスをとってプログラムしていきたいね。

ハカセ 画面リセット

このコラムもこれがサイゴかもしれんと思うと……ワシじゃ、コラムのヌシことハカセじゃ。
さっきのプログラムではCOLOR15にモドさないでENDしておるから、その先にナニを打っても赤い字になるのう。COLOR命令を何度も使うプログラムじゃと、いつもCOLOR 15で終われるとはかぎらん。そこで、ベンリなワザを教えておくぞい。
“Rボタン + 左ボタン + STARTボタン”
こうDSiのボタンを押せば、画面がリセットされるのじゃ。
ACLSと命令を打っても同じことじゃが、キーボードを使うよりラクじゃろ?

スピードを変えてみよう

インテリ「次はどこを改造するのがいいかな。ゲームとしてちゃんとしてないのは……
ワンパク「そりゃ、敵のスピードが早すぎるコトだな! ゲームオーバーを作ってマスマスよくワカッたが、敵をオソくしねえとハナシにならねェぜ!
神崎「そう言えば、スピードをコントロールしてる部分がもうあったような……
ワンパク「! タシカに、オレとしたコトがワスレてたぜ!
0035#. @LOOP
0036#.  GOSUB @MYSHIP
0037#.  GOSUB @MYSHOT
0038#.  GOSUB @ALIEN
0039#.  GOSUB @SCORE
0040#.  WAIT(1)
0041#. GOTO @LOOP
メインループの中のWAIT(1)で1/60秒オソくしてたんだったな。じゃあ、コレをもっとオソくすりゃイイんじゃねェか?
0040#.  WAIT(20)
神崎「あれ? なんだか……
RUN
神崎「……あ、そうか。
ワンパク「し、シマッタ! 自機がオソいのは100歩ゆずっても、ショットがオソいのだけはガマンならねー!
というかコレ、ただゲームのテンポがユルくなったダケだな!
インテリ「そういうコトだね。WAITはその場でポーズするようなモノだから、ゲーム全体のスピードが変わってしまうんだ。
神崎「WAITじゃなくて、敵だけが遅くなるような改造にしないとダメなんだね。
ワンパク「ムムム……自分やショットはウゴくが、敵はウゴかない……ん? そう考えるとアンガイよくあるパターンじゃねえか?
インテリ「そう、敵を動かす部分をスキップすればいいってコトだね。
0117#. @EMOVE
0118#. IF ??? THEN @EPUT
0119#. ON ED(I) GOTO @RI,@DW,@LF,@DW
ある条件のトキ以外は敵の場所を変えないことにしたよ。
神崎「ずっとスキップしっぱなしじゃ動かなくなっちゃうから、このIF文で「何回かに1回だけ動く」ようにすればいいってことか……。
ワンパク「だいたいハナシが見えてきたゼ。こうすりゃイイんだな!
0085#. ’--- シンリャクシャ
0086#. @ALIEN
0087#. ESTOP=ESTOP+1
まず敵をウゴかすオオモトのところに、変数ESTOPをヨウイするぜ! コイツは敵を止めるSTOPためのフラグだな。
0088#. IF ESTOP==9 THEN ESTOP=0
こうやって、10回に1回はにモドるようにしておくゼ! アトは、スキップするジョウケンを……
0119#. @EMOVE
0120#. IF ESTOP THEN @EPUT
IF ESTOP THEN、ツマリESTOPがゼロじゃなければスキップする、ってコトにすればデキアガリじゃねえか!?
インテリ「おっ、やったじゃないか! これで敵のスピードだけが10分の1になったね。
ワンパク「ワレながら、ジョウタツぶりがミゴトだぜ……。
神崎「あれ? そういえばこの10回に1回はにもどるってパターンは……
ハカセ「どうやらオボエていたようじゃのう。ワンパク君のプログラムの、ドコを変えればいいかわかったかの?
ワンパク「オレのプログラムのシュウセイからのスタートかよ!
神崎「この88行目はやっぱりけずって……
0087#. ESTOP=ESTOP+1
0088#. IF ESTOP==9 THEN ESTOP=0
ワンパク「そしたら、数がフエるイッポウじゃねェか?
神崎「うーん、タシカにそうなんだけど。
0119#. IF ESTOP%9 THEN @EPUT
スキップの条件をこう書きかえれば、10回に1回だけFLOOR(ESTOP%9)の答が0になる……つまりスキップしないってコトになるよね。
インテリ「I=I+1でループするとき、I%Nと書くとが『の倍数』になるたびゼロまでおり返しながら1増えていく」。前におぼえたホウソクだね。
ハカセ「やってるコトは同じじゃが、IF文がひとつ消えてコンピューターにやさしく、短いプログラムになったのう。
ESTOPの数はサイゴまで増えっぱなしじゃが、このゲームではメモリーのゲンカイまで増える前にゲームオーバーになるから、これでもよかろう。
ワンパク「そこまでコウリツをモトめるその考え方、オレは気にくわねェな!
ハカセ「タシカに、ワンパク君のプログラムの方が初心者にはわかりやすいとも言えるわい。
どこまでプログラムにコウリツを求めるべきか、それはプログラマーにとってエイエンのテーマじゃ。
インテリ「どれがセイカイとも言えない、ってコトかな。ちなみにスキップする回数はちょっと変わるけど、こういう方法もあるよ。
0087#. ESTOP=(ESTOP+1) AND 7
#####.  :
0119#. IF ESTOP THEN @EPUT
ビット演算のくわしいセツメイはもうはぶくけど、9回に1回だけESTOPがゼロになってスキップしなくなるプログラムだね。
コンピューター的にはわり算よりビット演算の方が早いから、ボクはI%Nを使うよりもスキかなあ。
ワンパク「ケッキョク、プログラムするヤツのスキズキってコトか……。
ハカセ「セイカイがひとつとかぎらんのも、プログラムのおもしろさじゃな。プログラマー2人に合作させるとおたがいのビガクがぶつかって、見ていてオモシロいもんじゃよ。
神崎「……やじうま?

クリア画面をつくってみよう

ワンパク「スピードが変わって、だいぶゲームらしくなってきたな!
インテリ「敵が少なくなると、デタラメに撃っても当たらなくなるのがよくわかるね。だけどあんまりじっくり当てようとしていると、敵にせめこまれてゲームオーバーになっちゃう。ゲームにはこういうカケヒキがないとね。
ハカセ「なんだかハジメてホメられた気がするわい……。
神崎「こうなってくると、敵を全滅させた時に何もないのがさびしいね。ゲームクリア画面を作っておこうよ。
ワンパク「そうムズカシくないんじゃねェか? とりあえず敵の数をチェックするための変数がいるな。
0012#. ELEFT=EMAX
敵の最大数を決める変数EMAXがもともとあったから、新しいEnemy残りLEFT変数ELEFTに使うことにするゼ!
インテリ「敵が1匹やられるたびに、変数ELEFTを1へらせばいいね。
0110#. ELEFT=ELEFT-1
あとはこの数がゼロになったら、ゲームエンドGame ENDでいいかな。
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
システム変数TCHSTFALSEだったら(タッチされてなかったら)ショットをスキップする、っていうやり方だね。
ワンパク「そのままBUTTON()に置きかえればすむコトじゃねェか! ……ン?
この前にB=BUTTON()してるから、IF B AND 16と書けばAボタンを押してるのはワカるが……
インテリ「そのままそう書くと、THENの後のイミがちがっちゃうね。
スキップするのは変えたくないから、ここには「IF (Aボタンが押されていない) THEN @MSSKIP」と書きたいけど……。
神崎「えーと、ビット演算のときにおぼえたけど、BUTTON()で変数に入る数は、2進数に直すと第0ビットから1ケタずつ、スイッチになってるんだったよね。
十字ボタン↑1000001
十字ボタン↓2000010
十字ボタン←4000100
十字ボタン→8001000
Aボタン16010000
Bボタン32100000
 :   :
インテリ「たとえば「十字ボタン→」と「Aボタン」が同時押しされていれば、変数に入る数は2進数では011000になるね。
これにAND 16すると……
    011000
AND 010000
  = 010000

Aボタンの第4ビットだけが立っているかどうかわかる、というのがおさらいになるね。
ワンパク「オサライかよ、オレのキライなナガレだぜ……。
神崎「うーん……そして、Aボタンが押されていない時にAND 16すると……
    001000
AND 010000
  = 000000

ほかのボタンを押していても、答はゼロになるわけだね。あたりまえだけど……
ワンパク「オ、オイ! ソレじゃねえか!?
神崎「え?
ハカセ「! (……ワンパク君! 気づいたようじゃな……!)
ワンパク「AND 16すりゃ、Aボタンを押してないトキにはゼッタイになるんだろ?
イマまで使ったことのねェやり方だけどよォ、それなら「IF (Aボタンが押されていない) THEN @MSSKIP」ってのも書けそうじゃねェか!
0070#. IF B AND 16==FALSE THEN @MSSKIP
……ム。ヘンな書き方になった気もするが……
RUN
ワンパク「チクショウ! 合ってると思ったんだが……ウマく動いてねえ!
インテリ「いやいや、考え方はバッチリだよ。
ワンパク「ナニ?
インテリ「その書き方だと、「B=TRUEAND16==FALSE」のように読めちゃうから、おかしくなるんだね。カッコでかこんで、こうして書けばいいんだよ。
0070#. IF (B AND 16)==FALSE THEN @MSSKIP
神崎「ホントだ! これならうまく動くよ!
ハカセ「ワンパク君……イージーミスでつまずいたものの、あれだけニガテだったビット演算の考え方をキチンとリカイしたようじゃのう。ワシはうれしいぞい。
ワンパク「ダテにあのメンドクセェ講座をくぐり抜けてきたワケじゃねえぜ!

まとめのようなもの

インテリ「おぼえたコトは、なんでもムダにはならないってコトだね。
ビット演算にかぎらず、このBASIC講座で勉強したことは、イガイなところで役に立ったり、応用しだいでもっとイロイロな使いみちがあるハズさ。
ハカセ「そういうコトじゃな。読者のショクンも、このサンプルをさらに改造するコトから始めてみてはどうかな?
これまでの講座でおぼえた命令を組み合わせると、イガイにやりたいコトができたりするものじゃ。
神崎「たしかに、まだ改造したいポイントはいっぱいあるね。敵の種類をふやしてみたいし、プレイヤーが1機でおわりじゃなくてもいいよね。
ハカセ「もっとカラフルにするのもよさそうじゃな。敵がやられた時にバクハツパターンを出すなどもいいじゃろう。
こういう見た目のエンシュツはイガイに考えるところが多く、うまくいった時のジュウジツ感も大きいのでおすすめじゃぞ。
インテリ「やりたいコトに手が届かない時は、説明書をながめてみるのもいいかもね。
ムズカシそうだけど、ここまで読んだ今なら、何が書いてあるのかカナリわかるようになってるハズだよ。
ワンパク「……テメーら! 最後だけマジメな話でまとめて、さもキョウイク的な講座だったってカオしてんじゃねえぞ!

今回のまとめ

画面リセット
“Rボタン + 左ボタン + STARTボタン”を押せば、画面がリセットされます。
まとめ方
最後のほうで、みんないい子になって教育的なことでまとめれば、まるでいい講座だったように思い込めるものです。