ASP.NET Coreで3DのSpaceWar!のような対戦型ゲームをつくる(3)の続きです。クライアントサイドの処理を実装します。

cshtmlファイル

Pagesフォルダ内にSpaceWarフォルダを作り、そのなかにgame.cshtmlという名前でファイルを作成します。

Pages\SpaceWar\game.cshtml

JavaScript部分

グローバル変数と定数

JavaScriptのグローバル変数と定数部分を示します。

初期化の処理

ページが読み込まれたら初期化の処理をおこないます。

ここでやることはレイアウトの初期化、効果音やBGMをエンドレスで再生するためのイベントリスナーの追加、ThreeJSをつかって3D描画をするために必要な3Dオブジェクトの追加、カメラ、ライトの初期化、3D描画をするときに敵のプレイヤー名を表示するためのテキストフィールドの生成、レーダーを表示する部分の初期化などです。これらが完了したらAspNetCore.SignalRで接続を開始します。

効果音を再生するときのボリュームの調整をしています。効果音が再生されるのは、プレイ中チェックボックスにチェックされている場合だけです。

必要な3Dオブジェクトをシーンに追加

必要な3Dオブジェクトをシーンに追加する処理を示します。必要なものは最初にまとめて全部追加してしまい、非表示にしたい場合はカメラの資格外に移動させます。

自機をシーンに追加する関数を示します。この関数が実行されるときにはシーンは生成されています。

弾丸をシーンに追加する処理を示します。

火花をシーンに追加する処理を示します。

AddLines関数は3Dっぽく見せるためにX軸Y軸Z軸に平行な線をシーンに追加するためのものです。その処理を示します。

シーンにライトを追加する処理を示します。平行光源だけだと影の部分が見えなくなってしまうので環境光もあわせて使用しています。

接続成功時の処理

AspNetCore.SignalRで接続することができたらサーバーサイドからSuccessfulConnectionToClientが送信されます。これを受信したらIDを表示させます。またゲームスタートのボタンが表示されるようにします。

接続に成功したとき、自分自身や他のユーザーがゲームに参加したときとゲームオーバーになったとき、離脱したときはサーバーサイドからNPCの数が送られてきます。この値が0でない場合はゲームを開始することができます。0のときは満員状態なので参加できません。この状態の変化にあわせてゲーム開始ボタンを表示させたり非表示にします。

ゲームスタートボタンを押した場合はサーバーサイドにGameStartが送信されます。これがサーバーサイドで受信されたときはゲーム開始の処理がおこなわれます。

ゲームスタートのボタンをおしてサーバーサイドで正常に処理がおこなわれた場合、サーバーサイドからEventGameStartToClientが送信されます。これを受信したらゲーム開始ボタンを非表示にしてisPlayingフラグをtrueにします。

キーが押されたらこれをサーバーサイドに送信するのですが、3Dで飛行機のようなものを操縦するゲームの場合、上と下のキーの役割が入れ替わっている場合があります。上昇するときは操縦桿を手前に引く動作をするため↓キーが上昇で、操縦桿を押す動作にあたる↑が下降にあたるわけです。ここは人によって切り替え可能にしたほうがよいと思い、チェックボックスで切り替え可能にしています。

キー操作をサーバーサイドに送信する

キーのコードでサーバーサイドに送ることができる上下左右、弾丸発射のコマンド文字列を取得する関数を示します。

キーが押されたり離されたときに実行される処理を示します。

更新処理

更新処理が必要なときはサーバーサイドからクライアントサイドにUpdatePlayersToClient、UpdateBulletsToClientなどが送信されます。MoveShip関数は3Dオブジェクトを移動させたり回転させるためのものです。

サーバーサイドからUpdatePlayersToClientが送信された場合は自機と敵機を上記のMoveShip関数を呼び出して移動させます。

カメラの座標がサーバーサイドから送られてきたら、カメラをこの座標に移動させ、自機が生きているなら存在する座標に向かせます。

弾丸の位置はUpdateBulletsToClientで送られてくるのでその位置に移動させます。

火花の座標はサーバーサイドからUpdateSparksToClientで送られてします。これを受信したら火花を移動させます。

クライアントサイドにおける更新処理で必要なデータがすべてサーバーサイドから送信された場合、EndUpdateToClientが送信されます。これを受信したらレンダリングをおこないます。

スコアや残機にかんする状態が変化するときはサーバーサイドからUpdateScoreToClientが送信されます。これを受信したら表示を変更します。

自分自身を含むすべてのプレイヤーの状態が変更された場合はUpdatePlayerInfosToClientが送信されるので、これを受信したら表示を変更します。

プレイヤーが別のプレイヤーを撃破した場合はサーバーサイドからSendHitCheckToClientが送信されます。これを受信したら配列に格納し、3秒間その内容を表示します。3秒経過したら古い通知は削除して表示されないようにします。

サーバーサイドで自機にかんするイベントが発生した場合、クライアントサイドにShotEventToClientやBeingAttackedEventToClientが送信されるので、対応する効果音を鳴らします。

ゲームオーバーになったときはBGMが鳴っているときはこれを停止してゲームオーバーの効果音を鳴らします。また残機が表示されていた部分に「GAME OVER」の文字列を表示させます。また非表示にしていたスタートボタンを再表示させます。