diff --git a/apps/client/src/network/handlers/GameHandler.ts b/apps/client/src/network/handlers/GameHandler.ts index ea9f08e..c5f42c6 100644 --- a/apps/client/src/network/handlers/GameHandler.ts +++ b/apps/client/src/network/handlers/GameHandler.ts @@ -17,6 +17,7 @@ MovePayload, NewPlayerPayload, PlaceBombPayload, + PlayerDeadPayload, RemovePlayerPayload, UpdateMapCellsPayload, UpdatePlayersPayload, @@ -46,6 +47,8 @@ offBombPlaced: (callback: (payload: BombPlacedPayload) => void) => void; onBombPlacedAck: (callback: (payload: BombPlacedAckPayload) => void) => void; offBombPlacedAck: (callback: (payload: BombPlacedAckPayload) => void) => void; + onPlayerDead: (callback: (payload: PlayerDeadPayload) => void) => void; + offPlayerDead: (callback: (payload: PlayerDeadPayload) => void) => void; sendMove: (x: number, y: number) => void; sendPlaceBomb: (payload: PlaceBombPayload) => void; sendBombHitReport: (payload: BombHitReportPayload) => void; @@ -108,6 +111,9 @@ const bombPlacedAckSubscription = createSubscriptionPair( protocol.SocketEvents.BOMB_PLACED_ACK ); + const playerDeadSubscription = createSubscriptionPair( + protocol.SocketEvents.PLAYER_DEAD + ); const sendMovePayload = createPayloadSender(protocol.SocketEvents.MOVE); const sendPlaceBombPayload = createPayloadSender(protocol.SocketEvents.PLACE_BOMB); const sendBombHitReportPayload = createPayloadSender( @@ -179,6 +185,12 @@ offBombPlacedAck: (callback) => { bombPlacedAckSubscription.off(callback); }, + onPlayerDead: (callback) => { + playerDeadSubscription.on(callback); + }, + offPlayerDead: (callback) => { + playerDeadSubscription.off(callback); + }, sendMove: (x, y) => { const payload: MovePayload = { x, y }; sendMovePayload(payload); diff --git a/apps/client/src/scenes/game/GameManager.ts b/apps/client/src/scenes/game/GameManager.ts index 498b49c..4e72924 100644 --- a/apps/client/src/scenes/game/GameManager.ts +++ b/apps/client/src/scenes/game/GameManager.ts @@ -4,7 +4,11 @@ * マップ,ネットワーク同期,ゲームループを統合する */ import { Application, Container, Ticker } from "pixi.js"; -import type { BombPlacedAckPayload, BombPlacedPayload } from "@repo/shared"; +import type { + BombPlacedAckPayload, + BombPlacedPayload, + PlayerDeadPayload, +} from "@repo/shared"; import { socketManager } from "@client/network/SocketManager"; import { AppearanceResolver } from "./application/AppearanceResolver"; import { GameMapController } from "./entities/map/GameMapController"; @@ -162,6 +166,9 @@ onBombPlacedAckFromNetwork: (payload) => { this.applyPlacedBombAck(payload); }, + onPlayerDeadFromNetwork: (payload) => { + this.handlePlayerDeadFromNetwork(payload); + }, }); this.networkSync.bind(); } @@ -233,6 +240,14 @@ return true; } + private handlePlayerDeadFromNetwork(payload: PlayerDeadPayload): void { + if (payload.playerId !== this.myId) { + return; + } + + this.lockInput(); + } + /** * クリーンアップ処理(コンポーネントアンマウント時) */ diff --git a/apps/client/src/scenes/game/application/GameNetworkSync.ts b/apps/client/src/scenes/game/application/GameNetworkSync.ts index 5d1f28a..1a910e1 100644 --- a/apps/client/src/scenes/game/application/GameNetworkSync.ts +++ b/apps/client/src/scenes/game/application/GameNetworkSync.ts @@ -10,12 +10,13 @@ CurrentPlayersPayload, GameStartPayload, NewPlayerPayload, + PlayerDeadPayload, RemovePlayerPayload, UpdateMapCellsPayload, UpdatePlayersPayload, } from "@repo/shared"; import { socketManager } from "@client/network/SocketManager"; -import { AppearanceResolver } from "@client/scenes/game/application/AppearanceResolver"; +import { AppearanceResolver } from "./AppearanceResolver"; import { LocalPlayerController, RemotePlayerController } from "@client/scenes/game/entities/player/PlayerController"; import { GameMapController } from "@client/scenes/game/entities/map/GameMapController"; import type { GamePlayers } from "./game.types"; @@ -32,6 +33,7 @@ onGameEnd: () => void; onBombPlacedFromOthers: (payload: BombPlacedPayload) => void; onBombPlacedAckFromNetwork: (payload: BombPlacedAckPayload) => void; + onPlayerDeadFromNetwork: (payload: PlayerDeadPayload) => void; }; /** ゲーム中のネットワークイベント購読と同期処理を管理する */ @@ -45,6 +47,7 @@ private onGameEnd: () => void; private onBombPlacedFromOthers: (payload: BombPlacedPayload) => void; private onBombPlacedAckFromNetwork: (payload: BombPlacedAckPayload) => void; + private onPlayerDeadFromNetwork: (payload: PlayerDeadPayload) => void; private isBound = false; private debugLog = (message: string) => { @@ -113,6 +116,10 @@ this.onBombPlacedAckFromNetwork(payload); }; + private handlePlayerDead = (payload: PlayerDeadPayload) => { + this.onPlayerDeadFromNetwork(payload); + }; + constructor({ worldContainer, players, @@ -123,6 +130,7 @@ onGameEnd, onBombPlacedFromOthers, onBombPlacedAckFromNetwork, + onPlayerDeadFromNetwork, }: GameNetworkSyncOptions) { this.worldContainer = worldContainer; this.players = players; @@ -133,6 +141,7 @@ this.onGameEnd = onGameEnd; this.onBombPlacedFromOthers = onBombPlacedFromOthers; this.onBombPlacedAckFromNetwork = onBombPlacedAckFromNetwork; + this.onPlayerDeadFromNetwork = onPlayerDeadFromNetwork; } public bind() { @@ -147,6 +156,7 @@ socketManager.game.onGameEnd(this.handleGameEnd); socketManager.game.onBombPlaced(this.handleBombPlaced); socketManager.game.onBombPlacedAck(this.handleBombPlacedAck); + socketManager.game.onPlayerDead(this.handlePlayerDead); this.isBound = true; } @@ -163,6 +173,7 @@ socketManager.game.offGameEnd(this.handleGameEnd); socketManager.game.offBombPlaced(this.handleBombPlaced); socketManager.game.offBombPlacedAck(this.handleBombPlacedAck); + socketManager.game.offPlayerDead(this.handlePlayerDead); this.isBound = false; }