今回は敵をつくります。Enemyクラスを作成します。

Enemyクラスの作成

敵を移動させる

敵を描画するだけであればこれで完成です。しかし敵は攻撃をしかけてくるのでその部分も作る必要があります。

敵の攻撃はほとんど垂直に弾丸を発射しながら落下し、地面にあたるまえに進路を上方に変更して退却します。弾丸はまっすぐ下に落ちるものだけではなく斜めに飛ぶ物もあります。

退却のときに機雷をおとしていきます。機雷は卵をかぶったひよこをつかいます。ひよこが卵を産むというのはおかしいかもしれませんが、今回はそのようにします。

上方に退却すると編隊の一番後ろに配置されます。攻撃は前列から順におこなわれ、前列がいなくなると編隊全体が下に向かって移動していきます。

敵は上空で待機している状態、下にむけて攻撃をしている状態、上方へ退却している状態、自機によって撃墜されてしまった状態の4つがあります。そこで以下のような列挙体を作成します。

退却してきた敵は最後尾に配置されますが、それぞれの敵が何列目にいるかわかるようにしておかないと最後尾がどの部分になるかわかりません。そこでEnemyクラスのフィールド変数にその敵が前(下)から何列目に配置されているかを格納しておきます。

Moveメソッドでは攻撃と退却時の動きだけ実装しています。待機状態でも前列の敵は前後(というか上下)に往復運動をしているのですが、この部分はGameManagerクラスで実装します。

当たり判定

自機の弾丸に当たったかどうかを判定する処理を示します。

敵弾を描画するためのEnemyBurretクラス

次に敵の弾丸を描画するためのEnemyBurretクラスを示します。直線を描画することでこれを敵弾とします。

GameManagerクラスにおける処理

GameManagerクラスの処理ですが、まずゲームが開始されたときに敵を表示させる処理をおこないます。

初期位置に敵を表示させる

敵は縦5列、横9列です。初期状態で何列目に存在するかで初期座標を求めます。

攻撃を開始させる

次に敵に攻撃を開始させる処理を示します。

1000 / 60 * 40秒おきに乱数で攻撃を開始する敵を求め、これを攻撃に参加させます。

まず最初に待機状態の敵のリストを取得してそのなかからEnemy.Lineの最小値を求めます。この最小値がEnemy.Lineである敵が攻撃開始可能な敵です。あとはこのなかから適当に選びます。

攻撃に参加する敵がきまったらEnemyStatusをAttackに変更して、右側に向かうか左に向かうかを決めます。あとはEnemy.Moveメソッドで処理がおこなわれます。攻撃を開始した場合、編隊全体を下方向に前進させます。

待機状態の敵の動き

待機状態にある敵の動きに関する処理を示します。上下に移動するのは前の2列だけです。そこで該当する敵を取得します。前の2列がどの敵を指すのかは攻撃を開始する敵や自機に撃墜されることで変化していきます。上下に移動している敵が一番上にきているタイミングで前2列の敵を取得します。

敵に動き全体をまとめるとこうなります。自機が死亡しているあいだは敵が新たに攻撃をしかけてくることはありません。これは立て続けに自機が死ぬことを避けるためです。

敵が退却したら編隊の後列に再配置されます。そのための処理を示します。

Enemy.Lineの最大値を求め、これと同じ敵がどれだけ存在するか調べます。もしその数がGameManager.ColumMaxよりも小さければ空きがあるということなのでその列に再配置します。もし空きがあければその後ろの列に配置します。最初は中央に、それ以降は左右交互の位置に配置できるようにNewPositionXという配列を作っています。

敵弾と機雷の投下

次に敵の弾丸を移動させる処理を示します。敵が攻撃を開始するとEnemy.MoveメソッドのなかでGameManager.EnemyBurretsに弾丸オブジェクトを格納するのでforeach文で移動処理をおこなうだけです。

それから機雷投下の処理も必要です。

まず機雷を描画するためのクラスを示します。

機雷を投下する示します。Enemy.Moveメソッドのなかで退却時にGameManager.DropMineメソッドが呼び出されます。そのとき50%の確率で機雷を投下します。ただし敵のX座標の絶対値が15を超えると自機の移動範囲を超えるのでその場合は投下しません。

機雷を移動させる処理を示します。Z座標が21を超えると着弾したことになります。

機雷の着弾

機雷が着弾したときの処理を示します。機雷が着弾したときForm1クラスで処理ができるようにイベントを発生させています。GameOverになっているときはイベントは発生しません。現在GameOverなのかどうかは残機が0かどうかで判断しています。

GameManager.UpdateメソッドとGameManager.Drawメソッド

これまでをまとめるとこうなります。

それから描画の処理も必要です。