Spacewar!の特徴として慣性力が働くため進行方向をすぐに変更できないことと、太陽の存在があります。画面中央にある太陽に近づきすぎると吸い込まれてしまうのです。今回は太陽の引力をプレイヤーに作用させる処理を追加します。

太陽を描画する

太陽を描画するクラスを作成します。太陽からは光がランダムに放たれています。この部分はDrawメソッドでおこないます。

太陽の引力

次に太陽が宇宙船を引き込む処理を示します。万有引力は距離の2乗に反比例します。ただここまで厳密にやる必要があるかは疑問ですが・・・。

Form1クラスの処理

それではForm1クラスの処理を示します。太陽を生成する処理が追加されました。それから太陽は画面の中心に描画されるのでフォームの大きさが変更されると太陽の位置もかわります。

各オブジェクトの移動

Timer.Tickイベントが発生したら自機と敵機、弾丸を移動させるとともに太陽の重力も作用させます。そのあと死亡判定をおこないます。

自機の移動はどのキーが押されているかでPlayer.AngleとPlayer.Accelerateメソッドを実行してPlayer.VXとPlayer.VYを変化させます。そのあとPlayer.Moveメソッドで座標を変化させます。敵の動作はEnemyMethodメソッド(後述)でおこないます。そのあと当たり判定をします。

スコア表示をする

自機と敵機、どちらか片方が死亡した場合、生き残ったほうに点数を加算します。衝突して両方が死亡した場合はノーカウントです。まずはそれぞれのスコアを記憶しておくためのフィールド変数をつくります。

当たり判定

当たり判定では自機と敵機が衝突したかを調べたあと自機と敵機が弾丸に接触していないかを調べます。

自機と敵機が衝突する前提は、判定前はPlayer.IsDeadがともにfalseであることです。この前提が存在する場合、Player.DoesRectangleOverlapメソッドをつかって敵機を衝突しているか調べます。衝突している場合は自機、敵機ともに死亡なのでそれぞれを引数にしてOnDeadメソッドを呼びます。

自機と敵機が衝突していないのであればそれぞれが太陽に衝突していないか、弾丸に当たっていないかを調べます。少なくとも片方が死亡している場合はOnDeadメソッドが呼び出されます。

ゲームの再開

自機または敵機死亡の場合は爆発の描画をして3秒後にリセットしてゲームを再開します。

描画処理

描画のためのOnPaintメソッドを示します。自機、敵機(死んでいなければ)、太陽、弾丸、爆発、スコアの描画をしています。