前回は宇宙船を生成して移動させ描画する処理を実装しました。

宇宙船をつくる Spacewar!をC#で作る(1)

今回は自機から弾丸を発射します。弾丸も残像があります。点を移動させその部分を記憶しておき、これを直線でつないで残像のように見せます。

弾丸を生成する

まずコンストラクタを示します。弾丸が通過した点を不透明度が異なる白線で描画するので、Penのリストを作成します。これは1つあればそれを使い回すことができるので静的メソッドで生成して、それを静的メンバーに格納します。

コンストラクタでは弾丸が生成される最初に描画される座標、初速を設定します。

移動の処理を示します。弾丸はどこまでも飛び続けるわけではなく標的に命中しなくても途中で消滅します。Moveメソッドが実行されるたびにLifeが減り、0になったら消滅します。

描画の処理を示します。これもPlayerクラスと同様に残像のように見せかけるために描画前に弾丸の位置をリストに保存して最新のAfterimageCount個だけを使います。宇宙船とちがって直線を描画するだけなので新しいものから不透明度を下げながら白線を描画しています。

複数の弾丸を移動し描画する

次に複数の弾丸を移動し描画する処理を示します。これまで弾丸のリストをForm1クラスやGameManagerのようなクラスのなかに作成していましたが、Burretクラス内に静的メンバーをつくってそこに格納すれば移動と描画の処理はBurretクラス内で完結します。そこで今回はその方式を採用します。自機が発射した弾丸にあたっても死ぬ仕様にしたいのでこちらのほうが合理的かもしれません。

弾丸を発射したらAddBurretメソッドで静的メンバーであるリストに追加していきます。そして静的メソッドであるMoveAllメソッドでLifeが0以下になっている弾丸や死亡フラグが立っている弾丸は取り除いて移動させ、DrawAllメソッドで描画します。

弾丸の当たり判定

次に当たり判定に関する処理を示します。Playerクラスに以下を追加します。

IsPointInsideメソッドは引数で渡されたPointがAngle度だけ回転している宇宙船が描画されている矩形の内部にあるかどうかを判定します。これは回転した矩形は重なっているか?とほぼ同じものです。

宇宙船同士の当たり判定

弾丸だけでなく自機と敵機が衝突した場合も考えられます。回転している自機と敵機が描画されている矩形が重なっているかどうかを判定するための処理を示します。これも回転した矩形は重なっているか?とほぼ同じです。

それからSpacewar!には中心に太陽があり、太陽の近くでは引力が働き太陽に衝突するとミスとなります。この当たり判定の処理は別のところで示します。

爆発の描画

次に爆発の描画をするために必要なSparkクラスを作成します。

火花の生成と描画

コンストラクタ内で最初に描画される座標と火花の移動速度を指定します。爆発で周囲に飛ぶ火花も残像があります。これも最初に描画のために必要なPenのリストを生成して、静的メンバーにこれを格納して使い回します。

火花の移動と描画の処理を示します。

新しく火花を追加したり、すべての火花を移動させ描画する処理を示します。

爆発の描画

最後に爆発の処理を示します。乱数で爆発地点から火花がどの方向にどのくらいの速度でいつまで移動するのかを決めます。