今回は敵機を作成します。とりあえず敵機は2種類です(気分が変わったら追加するかもしれない)。

敵機もCharacterクラスを継承してつくりますが、自機や弾丸に存在しない要素として撃墜したときの得点や進行方向を変更などがあります。敵機の共通部分なのでEnemyBaseクラスを作成して、これを継承して各敵機クラスを作ります。

EnemyBaseクラスはこれだけです。進路変更や弾丸発射のために必要な乱数を持たせています。

次にひとつめの敵機クラスを作成します。ひとつめの敵機は途中まで下まで来て進路反転して上昇します。そしてその際に弾丸を発射します。早い話、プログラミング講座 第28回【シューティングゲーム作成(8)/JavaScript】のマネです。

自機のY座標よりも 5大きい値よりもY座標が小さくなったらフィールド変数 doesAwayをtrueにして下降から上昇に転じます。そのときに弾丸を発射します。プログラミング講座 第28回【シューティングゲーム作成(8)/JavaScript】のそのまんまマネではおもしろくないので発射する弾丸を1発ではなく3発にして差別化(?)しています。

弾丸を発射する角度を求めるために自機の進行速度を考慮しなければなりません。それから弾丸を発射する角度を求めるためにアークタンジェントをもちいていますが、Math.Atanメソッドの戻り値が -π / 2 ~ π / 2 であることに対して、Math.Atan2では -π ~ π となります。そのためMath.Atanメソッドではπラジアン逆の値が取得されてしまうことがあります。

このとき弾丸の初速は

X方向ならMath.Cos(angle) * BurretSpeed、
Y方向ならMath.Sin(angle) * BurretSpeed + Form1.Speed

でよい。

ところが

とやってしまうと符号を入れ替えるか、angle += Math.PIとしなければならない場合があるのです。これに気づかず時間をとられてしまいました。

次に敵弾を描画するためのクラスを作成します。敵弾は最初にXY方向の移動量が決まるとその方向に飛び続けます。これも早い話、プログラミング講座 第28回【シューティングゲーム作成(8)/JavaScript】のマネをして飛行中にテクスチャを変更させます。

では敵キャラその1を描画する機能を追加してみましょう。Update()メソッド内でCreateEnemies()を実行して敵を生成するかどうかを決めます。敵を生成したらEnemiesリストに追加します。また撃墜された敵や描画する必要がない敵と敵弾はリストから取り除きます。

敵と敵を実際に描画する処理を示します。自機が存在しない場合と自機死亡の場合は敵と敵弾を表示しません。プログラミング講座 第32回【シューティングゲーム作成(12)/JavaScript】では敵は表示させて弾丸だけ発射しないようにしていますが、この部分はマネはしません(面倒くさくなった ← ってオイっ!)。