ASP.NET Coreでボンバーマンのような対戦型ゲームをつくります。

仕様は以下のとおりです。

同時にプレイできるのは4人まで。
プレイヤーが4人に満たない場合はNPCを入れる。
NPCが存在するときにゲーム開始ボタンを押すとプレイに参加できる。
残機制。残機0になったらゲームオーバー。その場合はNPCに入れ替える。
スコアは自分で仕掛けた爆弾で他のプレイヤーを倒したら1000点。
自分以外のプレイヤーによって他のプレイヤーが倒されたときは10点。
スコアランキングは30位まで表示。
プレイに参加できない場合も観戦は可能。

これまでは同時にプレイできるのは7人までで定員オーバーのときは他のページにリダイレクトさせていましたが、今回は4人までと少ないので観戦はできるようにします。

準備として

ゲームはBomberGame名前空間を定義して、そこで作成します。

最初に爆弾やブロックの位置、状態を管理するためのクラスを定義します。

Positionクラスは壁、爆弾、爆発時の火花の位置を管理するためのものです。キャラクタのサイズは32とし、15×15のマスのどこかに存在します。そのためX座標ならColumn * Game.CHARACTER_SIZEという計算式になります。

壁の位置、座標を管理するためのWallクラス(Positionクラスを継承)を定義します。

爆弾の位置、座標、状態を管理するためのBombクラス(Positionクラスを継承)を定義します。スコアを計算するときに誰が仕掛けた爆弾なのかがわかるようにPlayerプロパティを定義しています。

TimeToExplodeプロパティは爆発するまでの時間です。Updateメソッドが実行されるごとに減り0になると爆発しますが、近くにある爆弾の爆発で誘爆することもあります。その場合はExplodeメソッドを実行して爆発するまでの時間を短くします。

爆弾によって発生する火花の位置、座標、状態を管理するためのFireクラス(Positionクラスを継承)を定義します。火花が発生した場所のColumnとRowが一致したプレイヤーは死亡します。火花がどのプレイヤーによって発生したのかがわかるようにPlayerプロパティを定義しています。

Distanceプロパティは爆弾本体との距離です。0なら爆弾と同じ位置です。TimeToDisappearanceプロパティは火花が消滅するまでの時間です。

プレイヤーが爆弾によって撃破されたときに周囲に発生する火花の位置、座標、状態を管理するためのDeadFireクラスを定義します。この場合、火花は移動(等速直線運動)するので発生場所と初速をコンストラクタで設定します。Updateメソッドが呼び出されると初期位置と初速から現在位置を計算します。TimeToDisappearanceプロパティは消滅までの時間です。

Gameクラスの定義

次にゲームを管理するためのGameクラスを定義します。

インデントが深くなるので以降は以下のように名前空間を省略します。

定数部分

まず定数部分を示します。

プロパティ

各プロパティを示します。

IndestructibleWallsは爆弾でも破壊することができない壁、Wallsは破壊できる壁、BrokenWallsは1回の更新処理によって破壊された壁、Bombsは設置されている爆弾、Firesは爆発で発生した火花、DeadFiresはプレイヤーが撃破されて発生した周囲へ広がっていく火花です。

マップの初期化

マップを初期化する処理を示します。初期化がおこなわれるのは誰も接続されていない状態から最初のユーザーが訪問してきたときです。

mapTextの1の部分が爆弾でも破壊されない壁、0の部分がそれ意外の部分です。最初に4体のプレイヤーは四隅に登場するのですが、そのとき上下に2つ分だけ移動できるようにして、それ以外の部分は破壊できる壁で埋めてしまいます。

爆弾のセットと除去

爆弾をセットしたり除去するための処理を示します。

爆発時の処理

爆発に関する処理を示します。まず爆弾が爆発することで発生する火花の位置を取得する処理を示します。

爆弾が爆発したときの処理を示します。

まず該当する爆弾をBombsから取り除きます。そして上記 GetFirePositionsメソッドで取得したFireオブジェクトを_firesリストのなかに格納します。

このとき壁が破壊されるかもしれないのでそのチェックもしています。破壊された壁は一時的にBrokenWallsリストのなかに格納しておき、更新処理のときにクライアントサイドに送信できるようにしています。また爆発音を鳴らしたいのでイベントで通知できるようにもしています。

プレイヤーが撃破されたときの処理

プレイヤーが撃破されたときに四方八方に飛び散る火花を生成する処理を示します。

引数は撃破されたプレイヤーがいた座標です。ここを中心に乱数で初速を設定して24個のDeadFireを生成して周囲に火花が飛ぶようにしています。

移動できない位置と危険な位置を取得する

CreateDangerMapメソッドはNPCの動作を決定するときに必要になります。二次元配列を生成して移動できない場所に-1をセットします。移動できない場所とは壁がある位置、爆弾がセットされている位置、火花が存在する位置です。また爆弾が爆発すると火花が飛んでくる位置には爆弾との距離をセットしています。それ以外の移動可能で安全な位置にはint.MaxValueをセットしています。