2021年04月19日

師匠のVB.NETどたばた塾~第20回

sisyo.gif
師匠T:いたた……。師匠Tじゃ。

deshi.gif
弟子D:弟子Dだぜ! ……って、どうなさいましたか、師匠?

sisyo.gif
なんか腰や股関節のあたりが痛んでのう……。昨日寝違えたのが原因じゃろうか……。

deshi.gif
(師匠が体調不良? これは師匠を倒すチャンス!!)とりゃーっ!

sisyo.gif
超級ベーマガ王電影弾!!

deshi.gif
うわあっ。

sisyo.gif
腰や足を痛めたからといって、そうを簡単にわしを倒せると思ったか、愚か者めが。
さて、今回は、敵キャラについて、モジュール側の処理についてやっていくとするぞ。しっかとついてくるがよい。

deshi.gif
は、はい……。

【 少し改造するのじゃ 】

sisyo.gif
さて、さっそくじゃが、前回GraphModuleに追加したサブルーチンや関数のうち、いくつかを改造していくぞ。

deshi.gif
なんと。それはなにゆえです?

sisyo.gif
それは、MoveExにて、Select Caseで別々の移動処理に分岐させるのと同じ理由じゃ。いくつもの敵を出現させたいとき、それに対応できるようにするためじゃ。

deshi.gif
なるほど。

sisyo.gif
では、GraphModuleをこのように修正するがよい。赤枠が修正した部分じゃ。

vb2104-01.jpg

deshi.gif
あの、師匠。このOptionalというのはなんぞや。

sisyo.gif
うむ、それは、デフォルト値(省略した時に入る値)を許す時につけるものじゃ。これをつけると、省略した時に、指定した値(この場合は0じゃな)が設定した引数に入るのじゃ。
こうしておけば、呼び出し元は変えずに済むじゃろ? 別のグラフィックを使いたい時には、引数を指定すればよい。

deshi.gif
なるほど。

sisyo.gif
他の修正部分は大したことはしておらぬ。ハンドルを格納する変数を配列にし、その配列変数にハンドルを格納するようにして、さらにGetEnemyHnd関数では、渡した引数に応じた配列に格納されたハンドルを返すようにしただけじゃ。

deshi.gif
なるほど、わかりました!

sisyo.gif
うむ。それでは続いて、いよいよモジュール側の処理に取り組んでいくぞ!

【 いよいよ本題じゃ! 】

sisyo.gif
それではさっそく、EnemyModuleという名のモジュールを作り、処理を書いていくことにしようぞ。
刮目してみよ。これが、EnemyModuleの中身じゃ!!

vb2104-02.JPG
vb2104-03.JPG
vb2104-04.JPG
vb2104-05.JPG
vb2104-06.JPG

deshi.gif
おおっ!!

sisyo.gif
とはいっても、やっていることはShotModuleとほぼ同じじゃ。ポイントというポイントは、敵の位置を決めるところじゃな。今回は、出現するX座標はランダムに決めておる。GetRand()は、0から引数までの乱数(でたらめな数)を返す関数じゃ。

deshi.gif
ということは、createEnemyの

wx = SCREEN_X + GetRand(SCREEN_W - 32)

の部分は、SCREEN_X(画面の左端)から、SCREEN_W(画面の幅)までのランダムな位置を計算してるんですね。32を引いているのはなぜですか?

sisyo.gif
うむ、GetRand(SCREEN_W)にしたら、この値が最大値になったら画面右からはみ出してしまうからの。敵キャラのサイズだけ範囲を狭くしているのじゃ。

deshi.gif
なるほど。

【 敵の出現はどう制御する? 】

sisyo.gif
ではこれらのサブルーチン関数を、各所にはめ込んでいくとしよう。MainModuleのPlayInitとGameMainを、このように書き換えるがよい。赤枠が追加した部分じゃ。

vb2104-07.JPG

deshi.gif
なるほど。PlayInitで敵を全て消す処理を入れて、GameMainに、敵の移動処理と描画処理を入れてるんですね。PlayInitに、ついでにショットを全て消す処理を追加してるのは見なかったことにします。

sisyo.gif
うむ。さて、ここまでやってきたところで、一つ考えなければならんことがある。それは、敵の出現処理をどうするかじゃ。

deshi.gif
普通に、createEnemyを、GameMainに追加すればいいだけじゃないんですか?

sisyo.gif
ほう、それで大丈夫と思うかな? それではやってみよ。

deshi.gif
はい。かたかた……。動かしますね。

deshi.gif
ああっ! 敵キャラが! 次から次へと敵キャラがあああ!!

vb2104-08.JPG

sisyo.gif
どうじゃ、これではゲームにならんじゃろう。
それではどうするか、ということじゃが、それは次回のお楽しみとする。
次回はこれと、敵キャラと自機、ショットと敵キャラの当たり判定についてやっていくとするぞ。

deshi.gif
はい、師匠!

sisyo.gif
ふう……やっぱり腰が痛いのう。

deshi.gif
(チャーンス!)この講座は俺のものだー! とりゃー!

sisyo.gif
石歯天経拳ーーーー!!

deshi.gif
うわあっ。



※次の更新は、レトロゲーレビューの予定です。お楽しみに!

posted by 裏編 at 14:18| Comment(0) | 師匠のVB.NETどたばた塾 | 更新情報をチェックする

2021年03月15日

師匠のVB.NETどたばた塾~第19回

sisyo.gif
師匠T:うむ、師匠Tじゃ!

deshi.gif
弟子D:おう、弟子Dだぜ!

sisyo.gif
そういえば、もうすぐ春じゃのう。

deshi.gif
そうですね。

sisyo.gif
春といえば、彼氏と彼女のペアが……うおおおーーー!! 石歯天経けーんっっ!!

deshi.gif
お、落ち着いてください、師匠! 石歯天経拳ーーーー!!(師匠の石歯天経拳を自分の石歯天経拳で受け止める)

sisyo.gif
ぜぇぜぇ……す、すまぬ。つい、我を忘れてしもうた。

deshi.gif
はぁ……もしかして師匠……。

sisyo.gif
なんでもないぞ! カップルがうらやましいなぞと思ってないぞ! ほれ、さっそく今日の講座をはじめるぞ!

deshi.gif
まだ何も言ってませんが……。それで師匠、今日は敵キャラについてでしたっけ。

sisyo.gif
うむ。今回は、敵キャラの出現、移動、そして消滅についてやっていこうと思う。それではさっそくいくぞ! カップルのことが頭をよぎる前に!!

deshi.gif
はぁ……。

【敵キャラのクラスを作ろう!】

sisyo.gif
さて。まずは敵キャラを表すクラスを作るとしよう。まずは、プロジェクトメニューの『クラスの追加』から新しいクラスを作るとしよう。クラス名はEnemyとしておくぞ。

sisyo.gif
クラスを作ったところで、続いて、GraphModuleに次の変数、そして新しいサブルーチンと関数を付け加える。変数hndEmenyとLoadEnemyサブルーチン、GetEnemyHnd関数じゃ。
vb2103-01.JPG
↑付け加えた新しい変数と関数(赤枠が追加した部分)

deshi.gif
ふむふむ。画像読み込み処理と、ハンドルを返す関数を用意するんですね。

sisyo.gif
その通り。ここまでできたら、MainModuleのImageLoadサブルーチンにこう書き加える。LoadEnemyサブルーチンを呼び出すわけじゃな。
vb2103-02.JPG
↑ImageLoadサブルーチンをこう修正する(赤枠が追加した部分)

sisyo.gif
これができたら、改めてEnemyクラスの中身を書いていくとしよう。さっそく、コンストラクタを書くとするぞ。この通りじゃ。

vb2103-03.JPG
↑Enemyクラスのコンストラクタ

sisyo.gif
この通りじゃ。まず難しいことはなかろう? そうそう、いつものように、Class Enemyの下に、Inherits Spriteとつけるのと、さらにその下に、Dim fMoveType As Integerと書いておくのを忘れないようにの。
つまり、冒頭の部分をこう書き換えておくべし。

Class Enemy
    Inherits Sprite

Dim fMoveType As Integer
……

Public Sub New~

deshi.gif
はい。ですが、この引数pTypeや、変数fMoveTypeとはなんぞや?

sisyo.gif
うむ、それは敵の種類を表すものじゃ。敵にも色々な種類があるじゃろ? 突進してきたり、弾を撃ったら逃げていくものまで。

deshi.gif
はい。

sisyo.gif
今回は、敵は直進する敵一種類だけにする予定じゃが、複数の種類の敵を出す場合には、引数で敵の種類を設定するようにし、fMoveTypeの値で移動処理を分岐させるようにするのじゃ。

deshi.gif
なるほど。

sisyo.gif
さて、移動処理もこのクラスの中で行うようにする。MoveExサブルーチンじゃ。こうしとけば、モジュール側ではこの処理を呼び出すだけですむからの。

deshi.gif
なるほど! 確かにその通りです!

sisyo.gif
そういうわけで、移動処理がこちらじゃ。

vb2103-04.JPG
↑MoveExサブルーチンとMoveEx_Sub1サブルーチン

sisyo.gif
今回は、敵の種類を増やす時を考慮して、このようにSelect Caseを使って、それぞれ違うサブルーチンに飛ばす構造にしておる。
違う移動パターンを増やしたい時は、移動処理のサブルーチン(今回のMoveEx_Sub1のようなものじゃな)を増やし、Select Caseで分岐させて飛ばしてやるといいじゃろう。例えば1の時は、MoveEx_Sub2に飛ばす、というようにな。

deshi.gif
はい。

sisyo.gif
それでは、今回はここまで。次回は、モジュール側の処理を書いていくとする。復習をしっかりしておくようにの。
それでは!

deshi.gif
さらばだぜ!!

sisyo.gif
……。(--#



※次の更新は、フリーゲームレビューの予定です。お楽しみに!

posted by 裏編 at 18:28| Comment(0) | 師匠のVB.NETどたばた塾 | 更新情報をチェックする

2021年02月15日

師匠のVB.NETどたばた塾~第18回

sisyo.gif
師匠T:うむ、師匠Tじゃ。そういえば、昨日はバレンタインじゃったのう。

deshi.gif
弟子D:もしかして師匠……。

sisyo.gif
なんでもないぞ。今年は妹弟子Aからしか義理のイチゴショートしかもらってなくて寂しいだなんて思ってないぞっ!!(べきっ

deshi.gif
(師匠の握っていたクルミが……師匠の怒りと悲しみが、言葉なく伝わってくる……!)

sisyo.gif
さぁ、今回も初めていくとしようぞ。今回は、前回話した通り、今回付け足した四つの関数やサブルーチンについて説明していくぞ!

deshi.gif
は、はい……。

【 まずはEraseShotとClearShotからぢゃ! 】

sisyo.gif
まずは、LoadShotサブルーチンからといきたいところだが、これは難しいことはなかろう。ただ、GraphModuleモジュールのモジュール変数hndShotに、LoadGraph関数で、ショットの画像のハンドルを格納しているだけじゃ。

deshi.gif
ふむふむ。そして、GetShotHnd()関数は、そのhndShotの値を、戻り値として返しているわけですか。

sisyo.gif
その通りじゃ。こうしておけば、いちいちLoadGraph関数を実行する必要もなく、かつこれまでと同じように手軽にハンドルの値を取得することができるからの。

(前)
Handle = LoadGraph(~)

(後)
Handle = GetShotHnd()

deshi.gif
ふむふむ。

sisyo.gif
そして次。ShotEraseサブルーチンじゃな。

vb2102-01.JPG

sisyo.gif
これは、引数として、削除したいショットの配列の番号を受け取り、該当する配列oShot()にNothingを入れることによって、指定されたショットを消すサブルーチンじゃ。

deshi.gif
なるほど。次はShotClearですね。

vb2102-02.JPG

sisyo.gif
うむ。こちらは、そのShotEraseを利用して、For~Nextループを使って、配列oShot()の内容を全て削除するサブルーチンじゃ。例えば、自機が破壊されて、ゲームをやり直す場合、それまで残っていたショットが残っているとおかしいからの。

deshi.gif
なるほど。

sisyo.gif
それと、今回はショットは256個に限定したが、それより多かったり少ない数にしたい場合は、ショットの数を定数として用意し、それを使うとよい。その場合は、先ほどのFor文のToの後の数など、いくつかの数値を、この定数に変える必要があるがな。

(前)
For s = 0 To 255
Next

(後)
Const SHOTS = 255
……
For s = 0 To SHOTS
Next

sisyo.gif
こんなところじゃな。なお、定数はパブリック定数として定義したほうが、面倒がなくてよかろう。

deshi.gif
なるほど!

【 ShotExist関数じゃ! 】

sisyo.gif
そして最後。ShotExists関数じゃな。これは、引数で指定したショットがあるかどうかをTrueかFalseで返す関数じゃ。言うまでもないかもしれんが、存在していればTrue、なければFalseじゃ。

vb2102-03.JPG

deshi.gif
If文で、存在していればTrue、そして存在してなければFalseをReturnで返してるんですね。Is Nothingは、それがあるかどうかを判定する演算子、でしたっけ。

sisyo.gif
よく覚えておったの。その通り。それほど難しいことはなかろう。なお、今回はわかりやすくIf文を使ったが、もっと短く書きたい場合は、こんな風に書く方法もある。

----------
Return oShot(s) IsNot Nothing
----------

sisyo.gif
どちらの方法を使うかは、それぞれのプログラミングスタイルによるであろう。よく熟慮せよ。

deshi.gif
はい!

sisyo.gif
それでは次回は、敵キャラの出現、移動についてレクチャーする。復習を忘れぬようにな。



※次の更新は、『レトロゲーレビュー』の予定です。お楽しみに!

posted by 裏編 at 09:46| Comment(0) | 師匠のVB.NETどたばた塾 | 更新情報をチェックする

2021年01月25日

師匠のVB.NETどたばた塾~第17回

sisyo.gif
師匠T:ぶるるっ。今日も寒いのう。師匠Tじゃ。

deshi.gif
弟子D:本当に寒いですね、師匠。あ、弟子Dです。

sisyo.gif
本当に寒いのう。こんな時はあれじゃな。

deshi.gif
あれですね。

sisyo.gif
くあああああっ!! 答えよ弟子よ! B-Magaは!?

deshi.gif
旧ベー〇ガの風よっ!!

sisyo.gif
全身!

deshi.gif
痙攣!

sisyo.gif
電波狂乱!!

sisyo.gif
deshi.gif
見よ! 東方は、黄金(こがね)に萌えているうううぅぅぅ!!

sisyo.gif
さて、温まったのう。では始めるとするか。

deshi.gif
はい。でもこれって、ただの尺稼ぎのような気が……。

sisyo.gif
はあっ!!(弟子に飛び蹴り)

deshi.gif
うわあ。

sisyo.gif
さて。今回は、前回話した、ショットが途切れずに出て一本の線になってしまう問題の解決法と、処理をもうちっとスマートにする方法について説明していくぞ。

【 二つのアプローチがあるのだ! 】

sisyo.gif
さてさて。ショットが途切れずに出てしまう問題の解決じゃが、これには二つのアプローチ方法がある。

deshi.gif
二つ、ですか。まず一つ目は?

sisyo.gif
うむ。まず一つ目は、ちゃんとボタンを離して、押した時に発射されるようにする方法。これなら、押しっぱなしで連射ということはなくなるな。

deshi.gif
ですが、連打すると指が疲れますよ。それに、オート連射というものがある今日、手動連射というのもどうかと……。

sisyo.gif
そうじゃな。そこで二つ目の方法じゃ。二つ目は、押したままずっと発射するのは同じじゃが、次の発射までに間隔を置く、というものじゃ。これなら少なくとも、ショットが絶え間なく発射されて、一本の線のようになってしまう問題は解決される。じゃがその反面、プレイヤーの努力で連射速度を上げたり、ボスに接近して怒涛の連射を放つ、という芸当はできないのが難点である。

deshi.gif
ふむふむ。

sisyo.gif
どちらも一長一短がある。どちらの解決法を使うかは、自分の作るゲームの性質とよく相談して決めるがよい。今回は、二つ目の方法で解決していこうと思う。

deshi.gif
はい!

sisyo.gif
二つ目の方法じゃが、こんな感じじゃ。
・ボタンを押した時にカウンタを増やす。
・カウンタが一定の値になった時にショットを発射する。

deshi.gif
ふむふむ。

sisyo.gif
まず一つ目の処理だが、これは簡単じゃな。

deshi.gif
はい。MyCharaMoveサブルーチンの、発射ボタンを押したかどうかをチェックするIf文のところに、カウンタを増やす処理を入れるだけですよね。

sisyo.gif
その通りじゃ。二つ目の処理じゃが、これも難しいことはなかろう。カウンタがその一定値になったかどうかをIf文でチェックするだけじゃ。

deshi.gif
はい。

sisyo.gif
では、これを踏まえたうえで、処理を書いていくとしようぞ。まず、MyCharaModuleのModule MyCharaModuleの下に、次の一文を書くのだ。

Dim shotcnt As Integer

vb2101-01.JPG
↑追加した後のMyCharaModuleの先頭部分(赤枠が追加した部分

deshi.gif
はい、できました。

sisyo.gif
うむ。ではここからが本題じゃ。MyCharaMoveサブルーチンの、ボタンを押したかどうかをチェックする部分。

If (pad And PAD_INPUT_1) <> 0 Then

のすぐ下、ShotCreate()の文のすぐ上に、次のコードを書くがよい。

shotcnt = (shotcnt + 1) Mod 15

deshi.gif
はい。

sisyo.gif
さて。そしてラスト。ShotCreate()の部分を、こう書き換える。

If shotcnt = 0 Then
   ShotCreate()
End If

vb2101-02.JPG
↑上記の二つの修正を行った後はこうなります

sisyo.gif
それができたら完成じゃ。実行してみるがよい。

deshi.gif
おおっ! 確かに一定の間隔でショットが発射されてます! 線のようにはなってませんよ!

sisyo.gif
そうじゃろう。なお、Modの後の15を少なくすれば、連射速度が速くなるぞ。

deshi.gif
はい。でも、師匠、ちと疑問が。

sisyo.gif
なんじゃ?

deshi.gif
カウンタを増やしている部分なのですが、Modとはなんぞや。そして、どうしてこれを使っているのでしょうか?

sisyo.gif
うむ、いい質問じゃ。まず、Modとは割った時の余りを計算するものじゃ。例えば、15 Mod 2を実行すれば、余りである1が答えとして返ってくる。

deshi.gif
ふむふむ。

sisyo.gif
そして肝心の、なぜ使っているかじゃが、これも処理をシンプルにする工夫の一つじゃ。今回は、15カウントに1回発射するようにしているのだが、ここで、shotcntが13からの、値の動きを見てみよう。

deshi.gif
はい。

sisyo.gif
まず、13の時に押すと、13に1が加算され、14になる。そしてこれと15とのModは14となる。(商が0、余り14)

deshi.gif
ふむふむ。

sisyo.gif
そして次にこの処理に入った場合、14に1が足されて15になる。これと15とModをとると……?


deshi.gif
あっ! 0になってます!

sisyo.gif
そうじゃろう。15になったかどうかをチェックして、その時に発射と同時にカウンタを0にリセットするよりは、いくらかシンプルじゃろう。

deshi.gif
そうですね。

sisyo.gif
このように、プログラミングでは、わかりやすくするのはもちろん、できるだけシンプルに書くのが大切なことじゃ。精進せよ。

deshi.gif
はい!

【 別モジュールと関数を使い、処理をスマートにするのだ! 】

sisyo.gif
さて。このプログラムだが、実はいくつかスマートではない部分がある。まず一つは、Shotクラスのコンストラクタで、LoadGraphを使っているところだ。

deshi.gif
それはなにゆえです?

sisyo.gif
考えてみよ。このコンストラクタは、ショットが作られるたびに呼び出されるのだ。ということは、このLoadGraphも、ショットが作られるたびに呼び出されるのだぞ。ちょっとスマートではないと思わぬか?

deshi.gif
ああ、確かに。

sisyo.gif
あともう一つ。画面外に出たところでショットを消すところだ。ここでは、直接配列にNothingを入れているが、この後は、敵に当たったときにそのショットを消したり、ゲームの開始時に全ての配列をクリアしたりするのだぞ。

deshi.gif
確かにそれもちょっとスマートではないですね。

sisyo.gif
それと、EmptyShotID関数の中で、IsNot Nothingを使って、あるかどうかをチェックしているが、ここも、あるかどうかのチェックを、別関数で用意して、それを呼び出すようにしたほうがいいと思わぬかな?

deshi.gif
確かに。

sisyo.gif
そこで、新しいモジュールや関数を作り、それを使って処理をスマートにしようと思う。

deshi.gif
おおっ!


sisyo.gif
まず、最初の部分じゃ。新しく、GraphModuleというモジュールを作り、そこにLoadShotというサブルーチンと、GetShotHndという関数を作るのだ。

vb2101-03.JPG
↑LoadShot、GetShotHndを含めた、GraphModuleの内容

deshi.gif
はい。

sisyo.gif
それができたら、まず、MainModuleのImageLoad()サブルーチンに、LoadShot()サブルーチンを呼び出す処理を書く。

vb2101-04.JPG
↑LoadShot()を呼び出す処理を付け加えたImageLoadサブルーチン


sisyo.gif
そして最後。Shotクラスのコンストラクタの最初の部分……

Handle = LoadGraph("shot.bmp")

の部分を、こう書き換えるのだ。

Handle = GetShotHnd()

deshi.gif
はい、できました。


sisyo.gif
うむ。そうしたら実行してみよ。先ほどと動きは変わらぬはずじゃ。

deshi.gif
はい! ちゃんと動いてます!

sisyo.gif
うむ。それでは二つ目にうつろうぞ。次の二つのサブルーチンを、ShotModuleに作るのじゃ。ShotEraseサブルーチンと、ShotClearサブルーチンじゃ。

vb2101-05.JPG
↑二つのサブルーチン

deshi.gif
はい、作りましたよ。

sisyo.gif
そしたら、ShotMoveサブルーチンの、oShot(i) = Nothingの部分を、ShotErase(i)に置き換えるのじゃ。

vb2101-06.JPG
↑置き換えた後のShotMoveサブルーチン

sisyo.gif
このまま、三つ目もやってしまうぞ。先ほどと同じように、ShotModuleに、ShotExists関数を作るのじゃ。

vb2101-07.JPG
↑ShotExists関数

sisyo.gif
そして作ったら……

deshi.gif
EmptyShotID関数の、If文のoShot(i) Is Nothingの部分を……どうするんでしたっけ?

sisyo.gif
あともう一歩だったのに、惜しいのう。その部分を、Not ShotExists(i)に書き換えるのじゃ。
Notは、その後に続く条件が『合っていなければ』という意味になるので、この場合だと、『ShotExists(i)の結果がTrueでなければ(=ショットが存在してなければ)』ということになるのじゃ。

deshi.gif
なるほど。

vb2101-08.JPG
↑書き換えたEmptyShotID関数

sisyo.gif
おっと忘れていた。ShotMoveサブと、ShotDrawサブも、同じくIsNot Nothingを使っていたな。こちらも、該当する部分を、ShotExists(i)に置き換えよう。こちらには、Notはつけずともよいぞ。

vb2101-09.JPG
↑書き換えたShotMoveサブとShotDrawサブ

deshi.gif
はい。できました。実行してみますね……おおっ! 先ほどと変わらず動いてます!

sisyo.gif
うむ。うまくいったようじゃな。では今回はここまで。
次回は、先ほど追加した四つのサブルーチンや関数の内容を解説していくぞ。さらばぢゃ。

deshi.gif
さらばぢゃ~

sisyo.gif
……はあっ!!(弟子に飛び蹴り



※次の更新は、特集の予定です。お楽しみに!

posted by 裏編 at 10:35| Comment(0) | 師匠のVB.NETどたばた塾 | 更新情報をチェックする

2020年12月21日

師匠のVB.NETどたばた塾~第16回

sisyo.gif
師匠T:むぅ、いよいよ寒くなってきたの。風邪薬を飲むのが欠かせなくなってきたぞ。
いつも眠くてきついわい。

deshi.gif
弟子D:そのまま永遠の眠りにつかないように気を付けてください。……いや、ついてくれればこの講座は俺のものに……(飛び蹴りを喰らう

sisyo.gif
たわけが。この講座、そう簡単にお主に譲らぬわ。さて、今回は自機のショットについて説明していく。準備はよいかな?

deshi.gif
は、はい……。

sisyo.gif
ではいくぞ! 着いてくるがよい!

【 弾は配列変数で 】

sisyo.gif
さて。画面上に一つしかない自機とは違い、連射ができるSTGでは、ショットは複数画面の中に存在することになる。さて、このように複数存在しているものを扱うには、どうしたらいいかな?

deshi.gif
えーと、確か配列変数を使うんでしたっけ。

sisyo.gif
うむ、その通りじゃ。発射した時には、その配列変数から使われていないものを探し、それに情報をセットする。そして、移動、描画させるときには、使われているものに対し、その処理を行うようにするのじゃ。

deshi.gif
画面から出た時には、その配列を使われていない状態に戻すこともしなければなりませんね。

sisyo.gif
おぉ、いいことに気づいたのう。ということで、これがショットを表すShotクラスと、ショット関係の処理を行うShotModuleの内容じゃ。

vb2012-01.JPG
↑Shotクラス

vb2012-02.JPG
↑ShotModuleモジュール

sisyo.gif
では、まずはShotクラスから説明していくとしよう。
まずはコンストラクタから。と言っても、難しいことはない。引数として渡されたものを、クラス内の変数に格納してるだけじゃ。

deshi.gif
あの師匠。このfVX、fVYとはなんぞや。それとどうして、クラス内に移動処理を持たせてるんですか?

sisyo.gif
うむ、いい質問じゃ。このfVX、fVYは、ショットが進む方向じゃ。今回は、前方に直進させるだけだから必要ないかもしれんが、例えば3WAYにする場合だと、ショットごとに進む方向が変わるじゃろ? そこで、そのショットごとに移動量を設定させているのじゃ。クラス内にMoveEx()という移動処理を持たせているのも似たような理由からじゃ。この中で移動処理を持たせてやれば、ShotModuleでは、この処理を呼び出すだけで済むからの。

deshi.gif
なるほど。

sisyo.gif
それと、今回はショットが画面が消えたら、それを消す仕様にするので、ReviseプロパティはFalseにしておる。そして、モジュールの方で、そのショットのOutプロパティをチェックし、Trueになったらそのショットを消すようにする予定じゃ。

deshi.gif
なるほど!

【 空きショットを探そう 】

sisyo.gif
さて。では、ShotModuleの説明に入っていくとしよう。まずは一番の肝、使われていないショットを探す関数、EmptyShotID()関数じゃ。
vb2012-03.JPG


sisyo.gif
と言ってもやっていることは簡単。Forループでショットを扱う配列oShot()を探して使われていないものが見つかったら、その番号を戻り値に入れる、それだけじゃ。

deshi.gif
あの、師匠。この『Is Nothing』とはなんですか?

sisyo.gif
うむ。それは、その配列の中にオブジェクトが入っていないかどうかを表す演算子じゃ。入っていなければTrue、入っていればFalseを返す。なお、入っているかどうか(つまり入っていればTrue)を調べたければ、Isnot Nothingを使えばよい。

deshi.gif
ふむふむ。そういえば師匠、一つ質問が。

sisyo.gif
なんじゃ?

deshi.gif
ショットは、自機のところから出てくるものですよね。では、その自機の位置は、どうやって知るのでしょうか?

sisyo.gif
……あ。

deshi.gif
もしかして師匠……。

sisyo.gif
そ、それはこれから解説しようと思っていたところじゃ。MyCharaModuleに、次の関数を追加するがよい。

vb2012-04.JPG

sisyo.gif
これらの関数は、もし自機が存在していれば、その座標やサイズを返してくれる、というものじゃ。なお、もし自機がない場合は、-1を返すようになっておる。

deshi.gif
ふむふむ(感情のこもってない声で

sisyo.gif
うぅ、弟子の冷たい声が痛い。やはり新しい弟子をとるべきか……。

deshi.gif
そ、そんなことはありませんっ、師匠っ。俺は師匠を尊敬しておりますっ!

sisyo.gif
そうじゃろうそうじゃろう。では、それを踏まえたうえで、ショットを作るShotCreate()サブプロシージャの内容がこれじゃ。

vb2012-05.JPG

sisyo.gif
このサブプロシージャでは、まず先ほどのEmptyShotID()関数を使って、開いているショット配列を探し、その後、Shotクラスのインスタンスを作り、該当する配列に格納しておる。

deshi.gif
あの師匠。この数式がさっぱりわからないのですが。

sisyo.gif
何難しいことはない。ただ、ショットの初期位置を計算しているだけじゃ。

----------
MyX() + MyW() / 2 - 5 / 2
----------

sisyo.gif
この部分では、自機の横の中心を計算(X座標+幅/2)し、さらにショットの幅(5)の半分を引いている。中心を計算しただけでは、ショットの幅の分だけ右にずれてしまうからの。

----------
MyY() - 29
----------

sisyo.gif
この部分では、ショットが、自機の前に出現するように設定しておる。29というのは、ショットの高さじゃ。

deshi.gif
なるほど。

sisyo.gif
さて。ここまでくればあとは簡単。ShotMove()とShotDraw()だが、これも難しいことはない。ループで、ショットの配列を調べ、中にショットが入っているものがあれば、それを移動または表示させておるだけだ。
なお、移動させた時は、画面からはみ出たかどうかをOutプロパティを使って調べ、もしはみ出ていれば、ショットを消すようにしておる。

deshi.gif
ふむふむ。

sisyo.gif
ここまで出来たら、後はXキーを押した時に、ShotCreate()を呼び出し、さらにGameMain()の中に、ShotMove()とShotDraw()を呼び出すコードを書けばいいだけ。それが下のコードじゃ。

vb2012-06.JPG
↑MyCharaModuleの変更点

vb2012-07.JPG
↑MainModuleの変更点

sisyo.gif
これでショットを撃つ処理は出来上がりじゃ。実行してみよ。

deshi.gif
おーーー!! 弾が出る!……のはいいのですが、早く出すぎて、線みたいになってますよ。どうすればいいんでしょう?

sisyo.gif
それは次回に回しておこう。次回は、この件の解決と、処理をさらにスマートにする方法について解説していく。予習復習をしっかりするように。

deshi.gif
師匠もしっかりしてくださいね(冷たい瞳

sisyo.gif
弟子は、一番弟子の座が惜しくないと見えるな……

deshi.gif
そ、そんなことないです。俺はずっと師匠を尊敬しておりますよーーーー!!



※次の更新予定は、特集『パソレクSP・コマンドプロンプトを使いこなすのじゃ!』の予定です。お楽しみに! 更新は、1月9日ごろの予定です。

posted by 裏編 at 14:20| Comment(0) | 師匠のVB.NETどたばた塾 | 更新情報をチェックする