ASP.NET Coreで3DのSpaceWar!のような対戦型ゲームをつくる(2)の続きです。AspNetCore.SignalRにおける処理をおこないます。

以降は名前空間を省略して以下のように書きます。

接続時の処理

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

サーバーサイドに接続したら初回接続時のみタイマーの初期化をおこない、そのあとClientProxiesにClients.Callerを登録します。このとき接続ユーザー数が1の場合はSpaceWarGameオブジェクトの初期化をおこないます。

そのあとクライアントサイドに接続に成功したことを伝えます。他のプレイヤーの状態を表示させるための文字列を送信するために後述するSendPlayerInfosToClientメソッドを実行し、現在ゲームに参加することができるかをクライアントサイドで判断できるようにNPCの数を送信します(0が送信された場合は参加不可)。

切断時の処理

切断された場合はClientProxiesに登録されているIClientProxyを削除します。またこのユーザーがゲームに参加している場合はSpaceWarGameクラスのなかにある辞書からPlayerを削除する処理もおこないます。そして削除の処理がおこなわれた場合(SpaceWarGame.RemovePlayerメソッドがtrueを返した場合)はゲームに参加しているプレイヤーの状態(人数)が変わったことになるので、これを全ユーザーに伝えます。

ゲームスタート時の処理

接続しているユーザーがゲームに参加するときの処理を示します。

この場合はSpaceWarGame.AddPlayerメソッドを実行し、戻り値がnullかどうかを調べます。nullでない場合は新しいプレイヤーとして追加されたことになるのでそのユーザーにはEventGameStartToClientを送信して確かにゲーム開始の処理が成功したことを知らせます。またこの場合もゲームに参加しているプレイヤーの状態(人数)が変わったことになるので、これを全ユーザーに伝えます。

またSpaceWarGame.AddPlayerメソッドが返したPlayerオブジェクトにはイベントハンドラを追加して弾丸を発射したとき、NPCから狙われたとき、ゲームオーバーになったときにクライアントサイドで処理(効果音を鳴らす)ができるようにしておきます。

イベントハンドラ

追加されるイベントハンドラについて示します。弾丸を発射したときはクライアントサイドにShotEventToClientを、NPCに狙われた場合はBeingAttackedEventToClientを送信します。

ゲームオーバーになったときはスコアランキングに登録したあとクライアントサイドにGameOverEventToClientを送信して効果音を鳴らす処理をおこなわせます。

この場合もゲームに参加しているプレイヤーの状態(人数)が変わったことになるので、これを全ユーザーに伝えます。

更新処理

タイマーイベントが発生したときは全プレイヤーの状態を更新してから当たり判定の処理をおこないます。もし爆発が発生しているのであれば火花の状態も更新します。

そして接続しているユーザー全員に対して各プレイヤーの状態を伝えるためにUpdatePlayerNamesToClientとUpdatePlayerNamesToClientを送信します。また弾丸と火花の状態を伝えるためにUpdateBulletsToClientとUpdateSparksToClientを送信します。最後にクライアントサイドにおける更新処理で必要なものはすべて送信したことを伝えるためにEndUpdateToClientを送信します。

またプレイヤーに対してはカメラの座標と残機、スコアも伝える必要があります。そのためにUpdateCameraPositionToClientとUpdateScoreToClientを送信します。

当たり判定と結果の送信

以下は当たり判定の処理です。

結果の送信

SendPlayerInfosToClientメソッドは各プレイヤー(NPCは除く)のスコアと残機を表示させるために必要な文字列を送信するためのものです。その処理を示します。

キー操作への対応

キーが押されたり離されたときはPlayer.IsXXXKeyDownフラグをセットしたりクリアします。このとき送られてきたプレイヤー名をPlayer.Nameプロパティにセットしています。このとき名前のなかにカンマがあるとスコアランキングに登録するときに不具合を起こすので別の文字に置換しています。