diff --git a/apps/server/src/domains/game/GameLoop.ts b/apps/server/src/domains/game/GameLoop.ts index a36b44b..0e3ffa7 100644 --- a/apps/server/src/domains/game/GameLoop.ts +++ b/apps/server/src/domains/game/GameLoop.ts @@ -1,5 +1,5 @@ -import { Player } from "./entities/Player.js"; -import { MapStore } from "./states/MapStore"; +import { Player } from "./entities/player/Player.js"; +import { MapStore } from "./entities/map/MapStore"; import { gridMapLogic, config } from "@repo/shared"; import type { gridMapTypes } from "@repo/shared"; import { logEvent } from "@server/logging/logEvent"; diff --git a/apps/server/src/domains/game/GameManager.ts b/apps/server/src/domains/game/GameManager.ts new file mode 100644 index 0000000..cf8725f --- /dev/null +++ b/apps/server/src/domains/game/GameManager.ts @@ -0,0 +1,47 @@ +import { type TickData } from "./GameLoop"; +import { Player } from "./entities/player/Player.js"; +import { GameSessionService } from "./application/services/GameSessionService"; + +// プレイヤー集合の生成・更新・参照管理クラス +export class GameManager { + private gameSessionService: GameSessionService; + + constructor() { + this.gameSessionService = new GameSessionService(); + } + + // 外部(GameHandlerなど)から開始時刻を取得できるようにする + getRoomStartTime(roomId: string): number | undefined { + return this.gameSessionService.getRoomStartTime(roomId); + } + + // プレイヤー登録解除処理 + removePlayer(id: string) { + this.gameSessionService.removePlayer(id); + } + + // 指定プレイヤー座標更新処理 + movePlayer(id: string, x: number, y: number) { + this.gameSessionService.movePlayer(id, x, y); + } + + /** + * 20Hz固定のゲームループを開始する + * @param roomId ルームID + * @param playerIds このルームに参加しているプレイヤーのIDリスト + * @param onTick 毎フレーム実行される送信用のコールバック関数 + */ + startRoomSession( + roomId: string, + playerIds: string[], + onTick: (data: TickData) => void, + onGameEnd: () => void + ) { + this.gameSessionService.startRoomSession(roomId, playerIds, onTick, onGameEnd); + } + + // 指定ルームのプレイヤーを取得 + getRoomPlayers(roomId: string): Player[] { + return this.gameSessionService.getRoomPlayers(roomId); + } +} \ No newline at end of file diff --git a/apps/server/src/domains/game/GameSessionManager.ts b/apps/server/src/domains/game/GameSessionManager.ts index 021f3f3..ebd6505 100644 --- a/apps/server/src/domains/game/GameSessionManager.ts +++ b/apps/server/src/domains/game/GameSessionManager.ts @@ -1,5 +1,5 @@ import { type TickData } from "./GameLoop"; -import { Player } from "./entities/Player.js"; +import { Player } from "./entities/player/Player.js"; import { GameSessionService } from "./application/services/GameSessionService"; // ルーム単位セッションの生成・更新・参照管理クラス diff --git a/apps/server/src/domains/game/application/services/GameRoomSession.ts b/apps/server/src/domains/game/application/services/GameRoomSession.ts index f347020..845836d 100644 --- a/apps/server/src/domains/game/application/services/GameRoomSession.ts +++ b/apps/server/src/domains/game/application/services/GameRoomSession.ts @@ -1,8 +1,8 @@ import { config } from "@repo/shared"; import { logEvent } from "@server/logging/logEvent"; import { GameLoop, type TickData } from "../../GameLoop"; -import { Player } from "../../entities/Player.js"; -import { MapStore } from "../../states/MapStore"; +import { Player } from "../../entities/player/Player.js"; +import { MapStore } from "../../entities/map/MapStore"; export class GameRoomSession { private players: Map; diff --git a/apps/server/src/domains/game/entities/Player.ts b/apps/server/src/domains/game/entities/Player.ts deleted file mode 100644 index 6e16617..0000000 --- a/apps/server/src/domains/game/entities/Player.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { playerTypes } from "@repo/shared"; -import { config } from "@repo/shared"; - -// サーバー側保持プレイヤー状態モデル -export class Player implements playerTypes.PlayerData { - public id: string; - public x: number = 0; - public y: number = 0; - public teamId: number; - - constructor(id: string) { - this.id = id; - - // GAME_CONFIGからチーム数を動的に取得して割り当て - const teamCount = config.GAME_CONFIG.TEAM_COLORS.length; - this.teamId = Math.floor(Math.random() * teamCount); - } -} \ No newline at end of file diff --git a/apps/server/src/domains/game/entities/map/MapStore.ts b/apps/server/src/domains/game/entities/map/MapStore.ts new file mode 100644 index 0000000..a23f0ff --- /dev/null +++ b/apps/server/src/domains/game/entities/map/MapStore.ts @@ -0,0 +1,36 @@ +// apps/server/src/domains/game/entities/map/MapStore.ts +import type { gridMapTypes } from "@repo/shared"; +import { config } from "@repo/shared"; + +export class MapStore { + // 全マスの現在の色(teamId)を保持 + private gridColors: number[]; + // 次回の送信ループで送る差分リスト + private pendingUpdates: gridMapTypes.CellUpdate[]; + + constructor() { + // 初期状態は -1 (無色) などで初期化 + const totalCells = config.GAME_CONFIG.GRID_COLS * config.GAME_CONFIG.GRID_ROWS; + this.gridColors = new Array(totalCells).fill(-1); + this.pendingUpdates = []; + } + + /** + * マスを塗り、色が変化した場合のみ差分キューに追加する + */ + public paintCell(index: number, teamId: number): void { + if (this.gridColors[index] !== teamId) { + this.gridColors[index] = teamId; + this.pendingUpdates.push({ index, teamId }); + } + } + + /** + * 溜まっている差分を取得し、キューをクリアする(ループ送信時に使用) + */ + public getAndClearUpdates(): gridMapTypes.CellUpdate[] { + const updates = [...this.pendingUpdates]; + this.pendingUpdates = []; + return updates; + } +} \ No newline at end of file diff --git a/apps/server/src/domains/game/entities/player/Player.ts b/apps/server/src/domains/game/entities/player/Player.ts new file mode 100644 index 0000000..6e16617 --- /dev/null +++ b/apps/server/src/domains/game/entities/player/Player.ts @@ -0,0 +1,18 @@ +import type { playerTypes } from "@repo/shared"; +import { config } from "@repo/shared"; + +// サーバー側保持プレイヤー状態モデル +export class Player implements playerTypes.PlayerData { + public id: string; + public x: number = 0; + public y: number = 0; + public teamId: number; + + constructor(id: string) { + this.id = id; + + // GAME_CONFIGからチーム数を動的に取得して割り当て + const teamCount = config.GAME_CONFIG.TEAM_COLORS.length; + this.teamId = Math.floor(Math.random() * teamCount); + } +} \ No newline at end of file diff --git a/apps/server/src/domains/game/states/MapStore.ts b/apps/server/src/domains/game/states/MapStore.ts deleted file mode 100644 index 108308a..0000000 --- a/apps/server/src/domains/game/states/MapStore.ts +++ /dev/null @@ -1,36 +0,0 @@ -// apps/server/src/states/MapStore.ts -import type { gridMapTypes } from "@repo/shared"; -import { config } from "@repo/shared"; - -export class MapStore { - // 全マスの現在の色(teamId)を保持 - private gridColors: number[]; - // 次回の送信ループで送る差分リスト - private pendingUpdates: gridMapTypes.CellUpdate[]; - - constructor() { - // 初期状態は -1 (無色) などで初期化 - const totalCells = config.GAME_CONFIG.GRID_COLS * config.GAME_CONFIG.GRID_ROWS; - this.gridColors = new Array(totalCells).fill(-1); - this.pendingUpdates = []; - } - - /** - * マスを塗り、色が変化した場合のみ差分キューに追加する - */ - public paintCell(index: number, teamId: number): void { - if (this.gridColors[index] !== teamId) { - this.gridColors[index] = teamId; - this.pendingUpdates.push({ index, teamId }); - } - } - - /** - * 溜まっている差分を取得し、キューをクリアする(ループ送信時に使用) - */ - public getAndClearUpdates(): gridMapTypes.CellUpdate[] { - const updates = [...this.pendingUpdates]; - this.pendingUpdates = []; - return updates; - } -} \ No newline at end of file