サンプルプログラム7を見ていくのも、とうとう3回目です。
全4回でまだ1回分ありますが、今回がクライマックスです。
なぜならページの長さがいちばん長いからです。
ボス戦前のダンジョンとかこんな感じですよね。
今回は1章ごとにけっこうドンドン進みます。
そのスピードにおいていかれることもあるかもしれませんが、そんな時ははじめに戻って、きっちりわかったあたりで次に進むくらいがいいかもしれません。
なんだか勉強っぽくてイヤかもしれませんが、なにしろラストダンジョンです。
ワンパク君たちが迷うところではいっしょに迷いつつ、いっしょに戦っていきましょう。
ところで、「ワンパク君」とかあたりまえのように呼んでますが、あれ、本名なの?
ここまででプレイヤー側の動きはだいたいできあがったね。いよいよ敵の動きのプログラムに入ってみようか!
今までよりも大変そうなヨカン……。
ははは。たしかにタクサンの敵がジグザグに動き回るから、これまでよりもフクザツではあるね。
最初はカンタンに、スタートしたときのならび方から始めようか。
しかしプレイヤーキャラ1つ動かすだけでも、ケッコウ考えるコトが多いもんだぜ……。
カンタンって言っても、こういうワケじゃねェよな?
- LOCATE 0,3
- PRINT ”Е Е Е Е Е Е Е Е Е Е”
- LOCATE 0,5
- PRINT ”Е Е Е Е Е Е Е Е Е Е”
サスガにココまでカンタンじゃねェとは、オレにもワカるぜ。
たしかに、そうかも。サンプルをRUNしてみると、敵Еは1匹ずつ順に動いてるんだよね。ショットでやられたらその敵だけが消えるわけだし……。
つまり1匹ずつ、あわせて20匹ぶんの変数がいるわけだね。……こう言えば、今までにおぼえたコトが役に立つんじゃないかな?
そうか! 20個の変数をヨウイするんだな!
い、いや……
……じゃなくって、配列変数を使うんだよね。
そうそう、ソコだよ!
- DIM EX[20]:DIM EY[20]:DIM ED[20]
ゲームで使うのはこんなところかな。敵は英語で「Enemy(エネミー)」だから、変数の頭文字には「E」をつけることにするよ。
EXとEYはやっぱり、ヨコ(X)とタテ(Y)かな?
そうそう。ヨコがXでタテがYという変数の名付け方は、はっきりルールがあるワケじゃないけど、プログラマーの人はたいていこう書くね。おぼえておいていいんじゃないかな。
変数EDの「D」は「Dynamics (ダイナミクス)」のDなんだけど、……まあ、「動き方」くらいに考えておけばいいかな。
やけにハッキリしない言い方じゃねェか。ナニか言いたくないイミでもあんのか!?
「力学」とか「変動」とか……
おベンキョウの話だったか、キタイはずれだゼ!
ま、まあ分かりにくいのは本当かな。とにかく変数EDは敵がどう動くかのフラグにするってことだね?
そういうコト。とりあえず最初は0にしておいていいかな。
ネンのタメに、ここで配列変数をどう使うのかまとめておこうかのう。
たとえば1匹めの敵は配列の番号を[0]に統一するのじゃ。こやつのいる場所を調べたければ、横方向なら配列変数EX[0]、縦方向ならEY[0]じゃな。同じように2匹めの敵なら、EX[1]とEY[1]で場所が決まっているワケじゃ。
それとタダの書き方のモンダイじゃが、
- DIM EX[20]:DIM EY[20]:DIM ED[20]
というふうにコロン(:)で分けなくても、
- DIM EX[20],EY[20],ED[20]
と、ひとつのDIM命令でスッキリ書くこともできるぞい。
じゃあ、その3つの配列変数を使いながら敵をナラべてみるゼ!
- FOR I=0 TO 9
- EX[I]=I*2
- EY[I]=3
- ED[I]=0
- LOCATE EX[I],EY[I]
- PRINT ”Е”;
- NEXT
- FOR I=10 TO 19
- EX[I]=I*2−20
- EY[I]=5
- ED[I]=0
- LOCATE EX[I],EY[I]
- PRINT ”Е”;
- NEXT
……け、けっこうメンドくせェな、コレ!
イヤイヤ、なかなかジョウデキじゃぞい。トクに20行目なんかはクロウのアトがみえるのう。
敵が2列にならんでいるから、FOR文を2回に分けて作らないといけなかったんだね。
たしかに「FOR I=0 TO 19」ひとつで終わらせる方法ってないもんなあ。IF文で変数Iが10を超えたら……いやいや、それもプログラムが長くなっちゃう……
このタメだけに似たような行を2つ書くのがなんたってメンドクセェぜ!
実は、すごく短くする方法があるんだけど……
な、ナニ!? キキズテならねえな!
さっきのワンパク君のプログラムでも必要なコトはできてるから、わざわざ短くしなくてもいいんだけど……
イヤイヤ、さっきのプログラムを打つのはかなりメンドウだったんだぜ。短くなるならカンゲイじゃねェか?
ならば、こう書くと短くなるのう。
- FOR I=0 TO 19
- EX[I]=FLOOR(I MOD 10)*2
- EY[I]=FLOOR(I/10)*2+3
- ED[I]=0
- LOCATE EX[I],EY[I]
- PRINT ”Е”
- NEXT
ハ……ハァ!?
たしかに短いけど……よくわからない……
そうか、まだ習ってねェFLOORがカギだな! これにスゲェ意味が……
FLOORは「切り捨てて整数にする」命令だよ。たとえばA=FLOOR(1.75)と書けば変数Aには1.75から「.75」を切り捨てて1が入るね。
ふ、フツウだぜ!
「FLOOR(フロア)」すなわち「たいらにする」というイミじゃから、整数にするというイミに変わったのじゃな。
12行目の計算をカンタンに言いなおすと、「変数Iを10で割ったあまりから小数点以下を切りすてて2倍する」となるのう。
ぜんぜんカンタンじゃねー!
うーん、なるほど……たしかにEX[0]=0、EX[1]=2、EX[2]=4と2ずつ増えていって、EX[10]になったとたんEX[10]=0に戻っているね。やりたかったコト通りではあるんだけど……なんだかフシギだなあ。
13行目も、「Iを10で割って小数点以下を切りすてたら、2倍して3を足す」だけじゃがこれで敵の1〜10匹めまではタテ位置3行目に、11〜20匹めまではタテ位置5行目にそろうというワケじゃ。
ウ……ウウ……。ケイサンしてみたらタシカにその通りだったが……セイカツの中でまったく出てこねェ式にもホドがあるぜ!
あんまりパッと出てくる計算じゃないかもね。
でも「FLOOR(I/N)ならIが『Nの倍数』になるたび1増える」。
「FLOOR(I MOD N)ならIが『Nの倍数』になるたびゼロまでおり返しながら1増えていく」。
原理まで考えなくても、こう丸アンキしておくとプログラムで使えるバメンはけっこう多いよ。
たとえば時計を考えてみい。1時間は60分で、0分〜59分をくり返すものじゃが、この「分」はFLOOR(I MOD 60)で書きあらわせるのう。「時間」はFLOOR(I/60)と書けばいいワケじゃ。
かなりカタいたとえになってしまったが、サンプルプログラムのように、敵をセイレツさせるようなコトにも応用できるんじゃぞい。
プログラマーの生活のチエってところかな。
そういうコト。そうそう、ここでは「FLOOR(I MOD N)」なんて書いたけど、本当は「割り算のあまり」に小数が出てくるハズはないから、「I MOD N」と書くだけでいいんだよ。
ワシは……ワシは、見た目をそろえておきたかったのじゃああああ
敵をならべた後は、イヨイヨ動かすワケだが……
今までとちがって1方向や2方向じゃないのが、ナヤむところだね。
迷ったら、まずセイリしてみよう!
0 | 右に動く | X=49になるまでX+1 |
---|---|---|
1 | 下におりる | 1回だけY+1 |
2 | 左に動く | X=0になるまでX-1 |
3 | 下におりる | 1回だけY+1 |
キホン的には、このくり返しだよね。
そう言われれば、そう……なのか?
ショットで撃たれたり、下までおりて上にもどるのが抜けてるけど……
そこはもっとアトから考えよう! まずこの表にある動きをクリアーしないとそこまでたどりつかないしね。
そのワリキリ、キライじゃねえな! じゃあとにかくサブルーチン「ALIEN(エイリアン)」をメインルーチンから呼び出すことにするぜ!
- GOSUB @ALIEN
で、アトは……1匹ずつ動かすコトだけ考えるゼ!
- ’−−− しんりゃくしゃ
- @ALIEN
- FOR I=0 TO 19
- LOCATE EX[I],EY[I]:PRINT” ”
- GOSUB @EMOVE
- NEXT
- RETURN
動かすトキのキホンだから、” ”で消すだけは消しといたゼ。 こっからサキはナガくなりそうなんで@EMOVEにGOSUBさせといたが、モンダイはどの方向に動かすか……だな。
なかなかワルくないよ。飛んだ先でまた別のラベルに飛ぶけど、こうすると分かりやすいんじゃないかな。
- @EMOVE
- ON ED[I] GOTO @RI,@DW,@LF,@DW
ED[I]=0 | 右に動く | X=49になるまでX+1 |
---|---|---|
ED[I]=1 | 下におりる | 1回だけY+1 |
ED[I]=2 | 左に動く | X=0になるまでX-1 |
ED[I]=3 | 下におりる | 1回だけY+1 |
この表のとおりだね。フラグに使ってる変数ED[I]の数しだいで、ラベル@RI、@DW、@LF、@DWのどれかに飛ぶってやり方さ。
ああそうか、ラベルはそれぞれ「右(RIght)」「下(DoWn)」「左(LeFt)」になってるんだ。
とりあえず、右に動かすコトだけ考えるゼ!
- @RI
- EX[I]=EX[I]+1
- LOCATE EX[I],EY[I]
- PRINT ”Е”
- RETURN
コレで……まあ、右にだけはウゴくだろうな。
ずいぶんドンドン行くなあ。
でも、のこりの方向も同じように動かせそうだね。
- @DW
- EY[I]=EY[I]+1
- LOCATE EX[I],EY[I]
- PRINT ”Е”
- RETURN
やってるコトがカブる行が多いから、ゼンブをまとめるとこうなるかな。
- @RI
- EX[I]=EX[I]+1
- GOTO @EPUT
- @DW
- EY[I]=EY[I]+1
- GOTO @EPUT
- @LF
- EX[I]=EX[I]−1
- GOTO @EPUT
- @EPUT
- LOCATE EX[I],EY[I]
- PRINT ”Е”
- RETURN
ラベル名の「PUT(プット)」は日本語では「置く」というイミになるかな。敵キャラを画面に置くルーチンってことだね。
ココまではよし。……というか、まだ右に行くコトしかデキてねェな。フラグがED[I]=0のまんまだからな。
いまRUNしても、右ハジまで来たら表示がおかしくなるよ。
マカセとけ! たとえば@RIなら、右ハジに来たときだけフラグを変えてやりゃいいんだな?
- @RI
- EX[I]=EX[I]+1
- IF EX[I]<49 THEN @EPUT
- ED[I]=1
- GOTO @EPUT
てコトは、@LFでも同じようにできるハズだゼ!
- @LF
- EX[I]=EX[I]−1
- IF EX[I]>0 THEN @EPUT
- ED[I]=3
- GOTO @EPUT
ふむふむ。
ED[I]=0 | 右に動く | X=49になるまでX+1 | @RI |
---|---|---|---|
ED[I]=1 | 下におりる | 1回だけY+1 | @DW |
ED[I]=2 | 左に動く | X=0になるまでX-1 | @LF |
ED[I]=3 | 下におりる | 1回だけY+1 | @DW |
フラグED[I]が1や3になると、次はラベル@DWに行くことになるね。
@DWでは下におりるのは1回だけだから、すぐフラグを変えることになるね。
- @DW
- EY[I]=EY[I]+1
- IF ED[I]==1 THEN ED[I]=2
- IF ED[I]==3 THEN ED[I]=0
- GOTO @EPUT
こうやってIF文を使うことになるのかな?
ン? ……ああそうか、さっきまで右に動いていたとき(ED[I]==1)と、さっきまで左に動いていたとき(ED[I]==3)で、次に立てるフラグがカワッてくんのか。
せっかくだから、今まででおぼえたコトを使って、もっとシンプルにしてみようか。
- @DW
- EY[I]=EY[I]+1
- ED[I]=(ED[I]+1) AND 3
- GOTO @EPUT
……ナニ?
あ、ビット演算かあ……。
ケッ! オリコウさんドモはいつもこうだ! ウーム、2のトキは2進数で10で、3は2進数で11だから……ブツブツ……
えーと、ようするに86行ではED[I]のナカミが1だけふえるけど、4になったときだけは0にもどされるってコトだよね?
ワリとカンタンなんだけどなあ。
デキるヤツの考えのオシツケはマッピラだぜ!
ヒドい言われようだよ。まあ、ビット演算の話はもっと後からくわしくおぼえることにしようか。
そうそう、画面の下まで行ったらまた上から出てくる動きも足しておこうね。
- IF EY[I]>20 THEN EY[I]=3
ナルホドな。コレでとりあえず、敵の動きはひととおりデキたか……。
ずいぶんトントンビョウシじゃねェか。RUNしてみるか!
……なんか、ちがう……
ウオォー! ナンだこの動き、ナンかチガうぞコレ、っつかキモチワリー! なんかキモチワリー!
ふぉっふぉっふぉ。ようやく気づいたようじゃのう。めざしていた正しい動きはこっちじゃよ。
そうだコレだ。敵は下におりるトキは、1匹ずつじゃなくマトメて下におりるんだ。チクショウ、どこでマチガエたんだ!?
ここまでにミスがあったワケじゃないよ。まだそういう動きをプログラムしてないっていうだけさ。
ちょっとアタマをヒネるところだよ。いいかい?
今までは「1匹ずつ、右ハジ・左ハジに来たら下に行く」ことにしていたね。
うん、そのハズ。……そうだよね?
ムシロ、そのドコがワルいのかがワカらねーぜ!
ところが、ボクらがやろうとしてたのは「どれか1匹が右ハジ・左ハジに来たら、次のターンでは敵全部がその場から下に行く」動きなんだよ。
……!
つまりアレか、今までやってたのは行列を作って歩く「ムカデ歩き」の動きで、本当にやりたいのは行進の「右向け、右!」でゼンインがいつでも同じ方向をむく動きってコトか?
わりとヨウチじゃが、悪くないたとえじゃぞい。ココまでわかれば、アトはできるんではないかの?
待て待て待て、やるべきコトはだいたいワカったが、けっこうコンランするぜ!
急にハッソウを変えるところだからね。順にかたづけていこうか。
まず、方向を変えるきっかけは「どれか1匹が右ハジ・左ハジに来たら」だよね。ここから考えてみようよ。
それは、ツマリ……@RIや@LFの中の、IF文にひっかからなかったトキじゃねェか!
- @RI
- EX[I]=EX[I]+1
- IF EX[I]<49 THEN @EPUT
- ED[I]=1
- GOTO @EPUT
この81行目のあたりだな!
そうだね。ここでED[I]のフラグを変えてるけど、これだと[I]に入った1匹ずつ、右ハジにつくまでフラグが変わらないね。
ソレじゃマズいんだよな……そのカワリに、ゼンインのフラグを変える方法……?
もう1つ、大きなフラグを作ったらいいんじゃないかな!
- EDW=TRUE
81行目を新しい変数EDWのフラグを立てるように書きかえたよ。
このフラグが立ってる時は、どこにいる敵でもフラグED[I]を下におりるように変えたらどうかな?
フラグED[I]を変えるフラグがEDWか……ドンドンややこしくなってくるぜェ……。
ここがサイゴのカベだよ、がんばろう!
画面のハジに来たことはEDWで分かるようになったから、「次のターンで敵ぜんぶがその場から下に行く」動きをプログラムすればいいんだよね。
さっきのビット演算ED[I]=(ED[I]+1) AND 3を使えばそれでいいかな。
ムムム……。次のターンってことは、だいぶ前にモドるがこのあたりか。
- ’−−− しんりゃくしゃ
- @ALIEN
- FOR I=0 TO 19
- LOCATE EX[I],EY[I]:PRINT” ”
- GOSUB @EMOVE
- NEXT
- RETURN
ココのFOR〜NEXTで敵を動かしてたハズだぜ!
いちど敵のターンが終わってからED[I]のフラグを変えるわけだから……アレ? フラグを変えていい場所がないよ!?
ナニ言ってんだ……オ、オォ!?
なんてこった、タシカにそうだぜ! 70行目のアトでフラグを変えてもシッパイだし、72行目のアトじゃFOR〜NEXTループが終わってるからED[I]って書いてもナンにもならねェぞ!
ソコがモンダイだね。フラグEDWが立つのは敵のターンのトチュウだから、まず敵のターンが終わるまで待たなきゃいけない。でも敵のターンが終わったFOR〜NEXTの外だとED[I]を変えるコトができない。
ハマリじゃねェか! どうしようもねえ!
うーん、FOR〜NEXTが終わったあとに、もう1回こういうFOR〜NEXTを置くのはどう?
- FOR I=0 TO 19
- IF EDW THEN ED[I]=(ED[I]+1) AND 3
- NEXT
- EDW=FALSE
ED[I]を変えるためだけのFOR〜NEXTなんだけど……
やるじゃねェか。コレでバッチリに見えるぜ?
なかなかワルくないぞい。しかし、似たようなFOR〜NEXTを2回ツカうのはカイゼンのヨチありじゃ。
?
このテイドの長さなら気にならんじゃろうが、FOR〜NEXT文は増えれば増えるほど動作に時間がかかってしまうモノなのじゃ。ミライあるショクンには、これでマンゾクせずにFOR〜NEXTの少ないプログラムをメザしてもらいたいのう。
ムズカしいんだなあ。
そうなるとマスマスどうすりゃイイのかワカらねえじゃねーか!
ここは……もう1つフラグを使うことにしようか。
ED[I] | 敵1匹ずつ[I]の動きを決めるフラグ |
---|---|
EDW | 次のターンで敵ぜんぶが下におりるフラグ |
MD | 今のターンで敵1匹ずつ[I]下におりるフラグ |
この表のとおり、モンダイの動きをコントロールするための変数MDを使ってみるよ。
フラグMDが1匹ずつ動かすのはイイのか……? ああ、1匹ずつと言っても、FOR〜NEXTのターンまるごとMDフラグで動かしてるから、ケッキョク敵ゼンブまとめて動いてるのか……
マジでヤヤコシイな、ついてこれてるのか自分でもワカらねーぜ!
プログラムとしては、こういうことになるね。よく見直してみよう。
- ’−−− しんりゃくしゃ
- @ALIEN
- MD=FALSE
- IF EDW THEN MD=EDW:EDW=FALSE
- ’−−−
- FOR I=0 TO 19
- LOCATE EX[I],EY[I]:PRINT” ”
- IF MD==FALSE THEN @EMV
- ’−−−
- ED[I]=(ED[I]+1) AND 3
- ’−−−
- @EMV
- GOSUB @EMOVE
- NEXT
- RETURN
EDWフラグのことはFOR〜NEXTの外でかたづけて、ジッサイにED[I]を変えるのはMDフラグにマカせてあるのさ。
70行目でEDWフラグのナカミをMDフラグに引きつがせて、EDWフラグじたいは初期化してるんだね。
ココまでのプログラムを全部書くと、こんな感じかな。
+ | プログラムリスト |
|
ナンドでも言うが、ヤヤコシイぜ!
ひとつずつモンダイをカイケツしていくうちに、いつしかこうなってしまったワケじゃが、だれにでも見やすいプログラムかといえばギモンかもしれん。
全てがアタマに入ったところで、あらためて見やすいプログラムに書きなおすのもダイゴミじゃぞ。今すぐやるべきコトではないかもしれんが……
この講座がゼンブ終わったあとで、みんなやってみてね!
マル投げのフンイキがプンプンにおうぜ!
- DIM A[10],B[10],C[10]
- (変数)=FLOOR(数)
- FOR I=0 TO 100
- A[I]=FLOOR(I/5)
- NEXT
- FOR I=0 TO 100
- A[I]=I MOD 5
- NEXT
表示モード : [ スマホ・3DS対応表示 | クラシック表示 ]
PukiWiki 1.4.7 Copyright © 2001-2006 PukiWiki Developers Team. License is GPL. Based on "PukiWiki" 1.3 by yu-ji
ページの処理時間 : 0.536 秒 | このページの最終更新 : 2022/09/20 (火) 12:48:50 (565d) | ログイン
Copyright(C) 2011-2014 プチコンまとめWiki ◆1sxkymI8ji30