ASP.NET Core版 デジタルインベーダーをつくる(1)の続きです。

DigitalInvaderHubクラスの定義

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

接続時の処理

OnConnectedAsyncメソッドが初めて実行されたときはタイマーの初期化もおこないます。配列DigitalInvaderGame.Intervalsから値を取得してIntervalプロパティが異なるタイマーを配列の要素数個だけつくります。

以降は共通の処理です。Context.ConnectionIdをキーにしてClients.CallerとDigitalInvaderGameクラスのインスタンスを辞書に登録します。またDigitalInvaderGameクラスにおけるイベントに対応できるようにイベントハンドラを追加します。

ClientProxyMap.Countが0のときはサーバーへの負荷を考えてタイマーを停止させることにしています。もしClientProxyMap.Countが1になった場合は停止しているタイマーをスタートさせなければならないのでその処理を再開させます。

最後にクライアントサイドに接続に成功したことを通知するために”SuccessfulConnectionToClient”を送信します。

切断時の処理

通信が切断されたときはClientProxyMapとGamesからキーを削除します。

各イベントハンドラについて

DigitalInvaderGameクラス内イベント発生時の処理を示します。いずれもクライアントサイドに通知しているだけです。

ゲームスタート時の処理

ゲームをスタートするときに呼び出されるGameStartメソッドを示します。

辞書のなかにキー(引数id)に対応するDigitalInvaderGameを取得して、DigitalInvaderGame.GameStartメソッドを呼び出します。それと同時にgame.Nameプロパティにプレイヤー名をセットします。このとき名前にカンマが入っているとスコアランキングへの登録の処理で支障がでるので別の文字(”_”)に置き換えています。

処理が正常におこなわれたらクライアントサイドに”EventGameStartToClient”を送信します。

インベーダーを前進させる処理

Timer.Elapsedイベントが発生したらインベーダーを前進させる処理を行なうのですが、ステージによって対応するタイマーが違います。そこでDigitalInvaderGame.Stageステージの値とDigitalInvaderGame.Intervalsから適切なintervalを取得します。そのあとsenderからTimerを取得してIntervalプロパティが同じ場合だけDigitalInvaderGame.Updateメソッドを呼び出して更新処理をおこないます。

ゲームオーバー時の処理

ゲームオーバーになったらイベントハンドラGame_GameOverEventが呼び出されます。

ここではDigitalInvaderGameオブジェクトからNameプロパティとScoreプロパティを抜き取ってスコアランキングに登録する処理をおこなっています。そのあとクライアントサイドに”GameOverEventToClient”を送信しています。

キーが押下されたときの処理

ユーザーがキーを押下するたびにDownKeyメソッドが呼び出されます。このとき引数として渡された文字列が長すぎる場合は処理をおこないません(プレイヤー名は16文字までに制限しているのでスパム的なことをしない限り、ここで弾かれることはない)。

プレイヤー名のなかにカンマがある場合はスコアランキングへの登録で支障がでるので別の文字に置き換えています。そのあとDigitalInvaderGame.Nameプロパティにセットしています。そのあと第一引数を調べて”Z”であればターゲットの変更、”X”であればインベーダーを攻撃する処理をおこなわせています。