プチコン3号&BIGまとめWiki

プチコン3号&BIG 非公式初心者講座 : 第16章 サンプルプログラム7 (その4)

パンくずリスト

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

ついにサンプルプログラムを見ていく旅もここで終わりです。
RPGなら光とか青空とか出てくるムービーが始まるころですが、まだ今回もサンプルプログラムがゲームとして完成してはいないので、青空がふいにくもって真のラスボスが出てくる場面と言ったほうがいいでしょうか。
そこはどうだっていいですね。

今回はゲーム用語のいわゆる「当たり判定」から始まります。
思えばゲームっぽい話がたくさん出てくるサンプルプログラムでした。
あなたのプログラムのウデもかなり上がったんじゃないでしょうか。
これが終わったら、自分でカンタンなゲームを作ってみるのもいいかもしれません。

いまのは死亡フラグみたいなセリフでしたが、フラグのことも学んだあなたなら、このていどのフラグはFALSEにできるはずです。

敵を出してみよう

インテリくん

いままでのプログラムリストをゼンブまとめてみると、こうだったよね。

+  プログラムリスト
神崎

変数EMAXを敵の数に使うようになってるんだね。

ハカセ

敵の数をいつ変えたくなってもいいワケじゃな。前にもちらっと話したが、変数にできるトコロは変数にしておくのはダイジな心くばりじゃ。

ワンパクくん

まだデキてねェところは……ショットが敵に当たったトキ、か。

インテリくん

プログラムでショットが敵に当たるというのは、どういうコトかを考えるとわかるんじゃないかな?

神崎

うーん、ショットの場所と、敵の場所が重なったとき……かな?

ワンパクくん

ショットの場所は変数MXMYだったよな……。敵の場所はEX[I]EY[I]だから……。つまり、こんなカンジか!?

  1. IF MX==EX[I] AND MY==EY[I] THEN GOSUB @EOUT

配列変数をツカッてるから、敵をウゴかすFOR〜NEXTの中に入れないとイケねェな。

CHKCHR()命令

ハカセ

ワシじゃワシじゃ、今回はやたら顔を出すハカセじゃ。
ここでは話のナガレ的に出てこなかったが、当たり判定にベンリなCHKCHR()という命令があるのを知っておったかな?
このサンプルにはカンケイない話じゃが、カンタンにセツメイしておくぞい。

CHKCHR()命令
たとえばA=CHKCHR(0,0)と書くと、そのトキ画面の(0,0)のバショにナニが表示されているか変数Aに入るのじゃ。 (0,0)というのはLOCATE命令で使うのと同じヨコ方向とタテ方向の数じゃな。
文字コード
A=CHKCHR(0,0)と書いたトキに変数Aに入るのは、「文字コード」という数字じゃ。ナンのことかワカらんじゃろうが、実はプチコンでは1つ1つの文字に番号がわりふられているのじゃぞ。
ASC()命令
文字コードを調べる命令がASC()じゃ。
()の中に調べたい文字を入れると、その文字のコードがわかるのじゃ。例えば「Е」の文字コードを調べたければダイレクトモードでPRINT ASC(”Е”)と書いて実行すればいいのじゃ。57862と表示されるぞ。
CHR$()命令
ASC()とは逆に文字コードから文字を調べる命令がCHR$()じゃ。
例えばPRINT CHR$(57862)を実行すると「Е」が表示されるぞい。
今回のサンプルでは使い道はなさそうじゃが、覚えておいてソンはないじゃろう。

もし今回のサンプルのように、ショットの場所(MX,MY)に敵「Е」がいるかどうかチェックしたければ、IF CHKCHR(MX,MY)==ASC(”Е”) THEN〜とやればいいワケじゃな。
インテリくん

ここまではいい調子じゃないか。敵にショットが当たったコトが分かったら、次は敵がやられるルーチン@EOUTだね。

神崎
このサンプルだと、ショットが当たった敵はすぐに消えるから、敵を空白スペースで上書きすればいいのかな。
  1. @EOUT
  2. LOCATE EX[I],EY[I]:PRINT” ”
  3. RETURN
ワンパクくん

タシカにそうだが……ちょっと待てよ。コレだと、次に敵のターンがきたトタンに、消えた敵もまた出てきちまうぜ!

神崎

そうか、敵を動かすためにいつも書きなおしていたんだっけ。
いちどショットが当たった敵はPRINTしちゃダメってことだなあ。

インテリくん

これも、いままでの応用でなんとかなるんじゃないかな?

ワンパクくん

そうか! フラグを使うんだな!

神崎
敵1匹ずつに割りあたってるフラグっていうと、ED[I]だね。
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
インテリくん
消えたっていうトクベツなフラグだから、数字には−1をあてはめようか。
ED[I]=-1消えた表示しない@EOUT
113行に追加しておこう。
  1. @EOUT
  2. LOCATE EX[I],EY[I]:PRINT” ”
  3. ED[I]=−1
  4. RETURN
ワンパクくん

これでフラグは立ったから、次は敵の表示のトキにそのフラグを調べるのが……えーと、ドコがいいんだ?

インテリくん

Еを書いて消すなら、FORループの中ならどこでもいいとも言えるけど。でもどうせなら、もう表示しないってくらいがいいだろうね。

神崎
じゃあ、最初の方だね。
  1. FOR I=0 TO EMAX−1
  2.  IF ED[I]==−1 THEN @PASS
  1.  @PASS
  2. NEXT
  3. RETURN
これでED[I]フラグが−1のときは表示もされずに、次の敵まで飛ばされるよ!
ワンパクくん

待てよ……? ハハァ、ピンときたぜ!
こうなってくると敵が減れば減るほどごっそりスキップする行が多くなるよな。つまり、敵をタオせばタオすほど、ゲームのスピードが早くなるってワケだな!

ハカセ

ウムウム。どうやらショクンも、プログラムがダイブ身についてきたようじゃな。

ワンパクくん

負ける気がしねェゼ!

ハカセ

じゃが、せっかくならココで、よりコウリツのいいプログラムにチャレンジしてみんかな?

処理のスキップをおぼえておこう

ワンパクくん

コウリツときやがったか。プログラムが動けばそれでいいんじゃねェの?

ハカセ

ム……ム。そういう考えもたしかにアリじゃが。
ひとつにはプログラムの動作スピードが早くなるテクニックなので、オボエておけばアトアト「重い」プログラムを動かすのに助かる、というコトはあるぞい。

神崎

アクションゲームにある「処理落ち」とか、そういうやつ?

ハカセ

まあそんなトコロじゃな。もうひとつのメリットとしては、プログラムが見やすくなるコトもある、とも言えるのう。

ワンパクくん

「見やすくなるコトもある」……?

ハカセ

逆に見にくくなるコトも、ときにはあるかも……

神崎

えー……

ハカセ

ま、まァまァ! じゃからこそ、シンプルプログラムのイマのうちにオボエておこうという話じゃよ。なに、たいしてムズカしいコトではないぞい。

インテリくん

ハカセが言いたいのは、たぶんこの部分ですね。

  1.  IF MX==EX[I] AND MY==EY[I] THEN GOSUB @EOUT
ハカセ

さすがはインテリ君じゃな。さよう、ソコは「敵がやられたとハッキリ決まったら、やられルーチンに行って帰ってくる。それ以外は普通に進む」となっておる。

ワンパクくん

それでフツウじゃねえか?

ハカセ

しかし、こうすればどうじゃ。

  1.  IF MX!=EX[I] THEN @PASS
  2.  IF MY!=EY[I] THEN @PASS
  3.  ’−−− しぼう
  4.  LOCATE EX[I],EY[I]:PRINT” ”
  5.  ED[I]=−1
  6.  @PASS
  7. NEXT
ワンパクくん

ン? ……ンンン? 85〜86行目は、さっき作ったやられたトキのプログラムだよな。
82行目でMX!=EX[I]ってコトは、ショットのヨコ位置と敵のヨコ位置がチガうってコトだろ。ツマリ当たってないから、@PASSに飛ぶよな。

神崎

83行目のMY!=EY[I]もタテ位置になっただけで、同じことだね。
そのどっちでもないって時は、かならずショットが当たっているって言えるから、そのままやられたことになる……

ハカセ

さよう。もともとのMX==EX[I] AND MY==EY[I]という条件式は、ハッキリしとるがそれだけチェックに時間がかかるものじゃ。
新しいプログラムじゃと、カンタンな理由さえあればザクザク切っているのがワカるじゃろう。

インテリくん

やってるコトも、GOTOで飛ぶだけだしね。
それに、まだ敵のやられチェックをカンタンにする方法は残っているよ。

ワンパクくん

ツマリ今は「敵がゼッタイにやられてない」条件をサガせばいいってコトか? ……やられてないトキ……逆に言えば、やられるのはショットが当たったトキだけ……よし! ゼンゼンわからねえ!

神崎

ものすごくあきらめちゃったけど、たぶん「ショットが画面に出ていない間は、敵はやられない」と言えるんじゃないかな。

インテリくん

ソコだね! ショットは変数MSTで表示フラグをカンリしていたから……あとはカンタンだよね。

  1.  IF MST==FALSE THEN @PASS
ワンパクくん

ナルホドな。言われてみりゃ、そのとおりだぜ。……てことは、何も言われずにコレいきなり見たら、どういうイミなのかワカりづらくねェか?
スナオにIF MX==EX[I] AND MY==EY[I]って書いてあった方がカンタンじゃねえの?

ハカセ(泣)

ぜんぶヒテイされてもうたが……そのキモチも、ワカらんでもないわい。スピードを気にせんでいい初心者のコロなら、ムリしてまでやるコトではないのはタシカじゃ。

インテリくん

でも、人のプログラムリストを見るときに「どうしてこんな書き方を?」ってギモンはなくなるんじゃないかな。こういうプログラムの書き方があると知っておくのはムダじゃないよ。

ハカセ

ナイスフォローじゃ、インテリ君!
プログラムの書き方にはヒトそれぞれイロイロなポリシーがあるものじゃが、そういう考え方を知っておくのもひとつのベンキョウじゃぞ。

ワンパクくん

ベンキョウってヒビキは気にくわねェが……ツギからこういうスキップのしかたを見てもナットクできるのはタシカか。

当たり処理の仕上げをしよう

神崎

あれ? このプログラムRUNしてみると、ときどきショット1発で何匹も倒せることがあるよ。

ワンパクくん

ホントだな。こりゃアレだぜ、パワーアップとかによくある「カンツウダン」の動きになってるな!

インテリくん

「貫通弾」だね。シューティングゲームだと、敵に当たったらそこでショットは消える方がオーソドックスかな? このゲームならそうしないとカンタンすぎるしね。

神崎

ええと、敵に当たったらすぐにショットを消すわけだ。
さっきもやったけどショットの表示フラグは変数MSTだったね。

  1.  ’−−− しぼう
  2.  LOCATE EX[I],EY[I]:PRINT” ”
  3.  ED[I]=−1
  4.  MST=FALSE
ワンパクくん

1行ふやしただけか。イガイにアッサリいくんだな。

インテリくん

フラグはうまく使うと、いろいろラクになるものさ。

神崎

あとは、敵を倒したらスコアも上げないとね。

ワンパクくん

コレはそうムズカしくなさそうな気がするぜ。
とりあえず、サイショに画面の上の方に出しておくんだろ?

  1. LOCATE 0,0
  2. PRINT”SCORE: ”;SC

変数SCをスコアってことにしておいたぜ。

神崎

そして、敵がやられた時に10点プラスすれば完成かな。

  1.  ’−−− しぼう
  2.  SC=SC+10
  3.  LOCATE 7,0:PRINT SC
ハカセ

うむ、それで合っておる。合っておるのじゃが……。

ワンパクくん

ナンだ? RUNしても、ナニもモンダイはなさそうだぜ?

ハカセ

しかし、ワシとしてはこういうプログラムをテイアンしたい!

  1.  ’−−− しぼう
  2.  SV=SV+10
  1. @SCORE
  2. IF SV==0 THEN RETURN
  3. SC=SC+10
  4. SV=SV−10
  5. LOCATE 7,0:PRINT SC
  6. RETURN

メインループから@SCOREGOSUBすると考えてくれい。

ワンパクくん

どういうこった? 敵がやられたトキは、ただ変数SVに10点プラスして終わりかよ?

神崎

そのあとで、変数SCを変えてPRINTするのはサブルーチン@SCOREでやるんだね。そこで変数SVー10して、またゼロに戻る……

ワンパクくん

イミがワカらねェな! プログラムが長くなっただけじゃねえか!

インテリくん

先に言っちゃうと、これはLOADしたサンプルプログラムだとこうなってるんですよね。

ハカセ

さよう。なぜワシがこんな一見ムダに見えるプログラムにしたのか、ソコがワカるかの?

ワンパクくん

ムググ……サイゴになってイガイなナゾトキだぜ……。どう見てもムダにしか見えねェが……。

ハカセ

いやジッサイ、このプログラムのままじゃと、ホントにムダなのじゃ。

ワンパクくん

バカにしてんのか!

ハカセ

このサンプルプログラムはユーザーのショクンの手でカンセイさせるためのモノじゃからのう。そこでイミが出てくるように作ってあるのじゃよ。

神崎

うーん。そうは言っても、どういう時にヤクに立つのか……

インテリくん

こういう何のためにあるのか分からないプログラムは、関係のありそうな数をデタラメでも変えてみると、あんがい目に見えて分かるコトもあるよ。

ワンパクくん

というと、たとえば敵がやられたトキのSV=SV+10SV=SV+1に変えてみる、とかいうコトか?
ヤミクモにRUNしてやろうじゃねェか!

インテリくん

画面の前のみんなもジッサイに変えてためしてみよう!

img-screen-sample73.png
ワンパクくん

ウ、ウォオ!? 敵を1回撃ったら、スコアが上がりツヅケて止まらねー!

神崎

そうか……考えてみればこうなるのはトウゼンではあるよね。

ワンパクくん

アァ? ブツブツ……SVが1になってそのアト10引いてまたモドッて0じゃねェからまた10……フムフム。そりゃスコアがいつまでも上がりっぱなしにもなるな!

インテリくん

みんなもプログラムの流れを読むと、何が起きたのかだいたいわかるよね!

ハカセ

わざとデタラメにやっておるのじゃから、おかしな動きになるのはトウゼンじゃな。
しかし、このスコアを見てナニかに気付いたのではないかの?

ワンパクくん

いや、ベツに……

ハカセ(泣)

ココまでのナガレがダイナシになるのう……

神崎

あっ! スコアが10点ずつアニメーションで増えるように見えるよ!

ワンパクくん

そりゃタシカにそう見えるけどよォ……。メインループを1回通るたびに10点増やしてんだからトウゼンじゃ……ハッ!?

インテリくん

いいトコロに気付いたね。ギャクに言えば、メインループを1回通るたびに点を増やすようにすると、アニメーションで点数が増えて見えるワケだ。

ワンパクくん

ナゾがとけてきたゼ……こうすりゃハッキリするな。さっきSV=SV+1にしたトコロをSV=SV+100にしてRUNだ!

img-screen-sample74.png
ハカセ

うむ! 止まった画面ではよくワカらんが、ミゴトに1匹倒すごとに100点が入り、それが10点ずつアニメーションしておる。

ワンパクくん

サブルーチン@SCOREを通るたびに、変数SVがカラになるまで10点ずつ増えてるからな! コレはメインループの中でナンドも通ることにイミがあったってワケだ!

ハカセ

モトモトは、たとえば1匹だけ高得点の敵がいるとして、そいつを倒したときにボーナスっぽく、と作ったブブンだったんじゃが、コレももちろんセイカイじゃぞい。

ワンパクくん

まさかサイゴにこんなクイズがノコッてたとはな……。

インテリくん

プログラムをヒトに渡す時は分かりにくい処理にはコメントを付けておくのがキホンだけど、初心者向けのカダイとしては、まあ良かったんじゃないかな。

ハカセ(泣)

ケッキョクそういうアツカイなのかのう……?

今回のまとめ

当たり判定
いちばんオーソドックスな当たり判定は、ぶつけるモノの位置とぶつかられるモノの位置を比べることです。ヨコ座標とタテ座標が一致すれば、それは当たっているということになります。
CHKCHR()命令
  1. (変数)=CHKCHR(横座標,縦座標)
画面の指定した座標に、何のキャラクターが表示されているかが、文字コードで変数に入ります。
ASC()命令
  1. (変数)=ASC(”文字”)
入力した文字の文字コードが変数に入ります。
CHR$()命令
  1. (変数)=CHR$(文字コード)
入力した文字コードの文字が変数に入ります。

メニュー 【3号】

ヘルプ

リンク

最近の更新

最近の人気ページ

オンライン情報

  • 現在同時に 7 人がこのサイトを見ています
  • このページはこれまでに 1004 回、本日は 1 回、昨日は 0 回閲覧されました

ページの先頭に戻る

表示モード : [ スマホ・3DS対応表示 | クラシック表示 ]
PukiWiki 1.4.7 Copyright © 2001-2006 PukiWiki Developers Team. License is GPL. Based on "PukiWiki" 1.3 by yu-ji
ページの処理時間 : 0.154 秒 | このページの最終更新 : 2019/08/13 (火) 14:37:20 (199d) | ログイン
Copyright(C) 2011-2014 プチコンまとめWiki ◆1sxkymI8ji30