ASP.NET coreで対戦型『スペースウォー!』(Spacewar!)をつくる(1)の続きです。

今回はゲーム全体を管理するGameクラスを定義します。ゲームは対戦者以外の人も観戦できるようにします。

以降は名前空間部分を省略して表記します。

フィールド変数とプロパティ

フィールド変数とプロパティを示します。

コンストラクタ

コンストラクタを示します。

更新処理

更新時におこなわれる処理を示します。

2つのプレーヤーに太陽の重力を作用させ移動速度を変更させます。そのあとPlayer.Updateメソッドを呼び出してプレーヤーの座標を移動させます。そのあとCheckメソッドで当たり判定をおこないます。

太陽の重力を作用させる処理を示します。重力は距離の2乗に反比例し、中心にむかって作用します。

当たり判定

当たり判定の処理を示します。

片方がすでに死亡している場合は勝負がついているので当たり判定はしません。当たり判定は太陽に衝突したか?他のプレーヤーが発射した弾丸に接触したか?プレーヤー同士が衝突したか?を判定します。そのあと両プレーヤーの死亡フラグを調べてどちらが勝ったのかを判定します。

太陽に衝突したか?

プレーヤーが太陽に衝突したかを判定する処理を示します。

Player.OuterPointsをAngleだけ回転させてCenterX、CenterYだけ平行移動させるとプレーヤーの外周部分の座標を取得することができます。これら座標と中心座標と太陽の座標(中心部分)で一番距離が小さい部分と太陽の半径を比較します(実際には平方根を取る処理を省略して2乗を比較している)。太陽の半径よりも太陽との距離が小さい場合は太陽に衝突していることになります。

弾丸は命中したか?

ある点が複数の点で構成される図形の内部にあるかどうかを調べるメソッドを示します。これはC# JavaScript 不規則な形をした図形との当たり判定のものとほとんど同じです。

弾丸がプレーヤーに命中したかを調べる処理を示します。

Player.OuterPointsをAngleだけ回転させてCenterX、CenterYだけ平行移動させてプレーヤーの外周部分の座標を取得します。これらの点で構成される図形の内部に弾丸の先端部があれば弾丸は命中していることになります。

プレーヤー同士が衝突したか?

プレーヤー同士が衝突したかを判定する処理を示します。

Player0.InnerPoints(OuterPointsよりも内部より)を回転させて平行移動させた点の座標を取得し、これらの点で構成される図形の内部にPlayer1の内部にある点が存在するかを調べます。存在する場合は両者は衝突しています。

爆発発生の処理

爆発を発生させる処理を示します。

乱数を生成して爆発の中心点の周囲に時間差をつけて火球を生成します。爆発発生時には効果音も鳴らしたいのでExplodedイベントを定義します。

終戦処理

ひとつの戦闘が終了したあとにおこなわれる処理を示します。

OnSettledメソッドの引数は勝者の番号です。-1のときはプレーヤー同士が衝突したり相打ちで引き分けの場合です。勝者がいる場合はそのプレーヤーのスコアを1増やします。MAX_SCOREに達した場合はゲーム終了です。GameFinishedイベントを発生させて勝者と敗者を確定させてゲームを終了させます。そうでない場合は2秒後にプレーヤーの位置を元の位置に戻して次の戦闘画面に移ります。

イベントハンドラの引数に使われるGameFinishedArgsクラスを示します。勝者と敗者、Gameオブジェクトをプロパティとしています。