diff --git a/apps/client/src/entities/GameMap.ts b/apps/client/src/entities/GameMap.ts index 79577ff..e54dd9e 100644 --- a/apps/client/src/entities/GameMap.ts +++ b/apps/client/src/entities/GameMap.ts @@ -1,30 +1,97 @@ -import { Graphics } from "pixi.js"; +// apps/client/src/game/map/GameMap.ts (パスは適宜読み替えてください) +import { Container, Graphics } from "pixi.js"; import { GAME_CONFIG } from "@repo/shared/src/config/gameConfig"; +import type { MapState } from "@repo/shared/src/types/map"; -// マップ背景・グリッド・外枠の一括描画オブジェクト -export class GameMap extends Graphics { +// 親クラスを Graphics から Container に変更し、レイヤー管理を可能にする +export class GameMap extends Container { + private bgGraphics: Graphics; + private gridGraphics: Graphics; + + // 400個(GRID_COLS * GRID_ROWS)のマス目描画用オブジェクトを保持する1次元配列 + private cells: Graphics[] = []; + constructor() { super(); - this.drawMap(); + this.bgGraphics = new Graphics(); + this.gridGraphics = new Graphics(); + + // 描画順(追加した順に前面に描画される): 背景 -> マス目 -> グリッド線 + this.addChild(this.bgGraphics); + + // マス目の初期化と Container への追加 + this.initCells(); + + this.addChild(this.gridGraphics); + + // 背景と線の描画(静的なので1回だけ実行) + this.drawBaseMap(); } - // 設定値参照によるマップ外観組み立て処理 - private drawMap() { - const { MAP_WIDTH, MAP_HEIGHT } = GAME_CONFIG; + // 設定値に基づき、空のマス目(Graphics)を400個生成して配列に格納する + private initCells() { + const { GRID_COLS, GRID_ROWS, GRID_CELL_SIZE } = GAME_CONFIG; + const totalCells = GRID_COLS * GRID_ROWS; + + for (let i = 0; i < totalCells; i++) { + const col = i % GRID_COLS; + const row = Math.floor(i / GRID_COLS); + + const cell = new Graphics(); + // マスの座標をあらかじめ設定しておく(描画の基準点になる) + cell.x = col * GRID_CELL_SIZE; + cell.y = row * GRID_CELL_SIZE; + + this.addChild(cell); + this.cells.push(cell); + } + } + + // 設定値参照によるマップ外観(背景・グリッド線)の組み立て処理 + private drawBaseMap() { + const { + MAP_WIDTH, MAP_HEIGHT, GRID_CELL_SIZE, + MAP_BG_COLOR, MAP_GRID_COLOR, MAP_BORDER_COLOR + } = GAME_CONFIG; // マップ全域背景レイヤー - this.rect(0, 0, MAP_WIDTH, MAP_HEIGHT).fill(0x111111); + this.bgGraphics.rect(0, 0, MAP_WIDTH, MAP_HEIGHT).fill(MAP_BG_COLOR); - // 100px 間隔縦方向グリッド線 - for (let x = 0; x <= MAP_WIDTH; x += 100) { - this.moveTo(x, 0).lineTo(x, MAP_HEIGHT).stroke({ width: 1, color: 0x333333 }); + // 縦方向グリッド線 + for (let x = 0; x <= MAP_WIDTH; x += GRID_CELL_SIZE) { + this.gridGraphics.moveTo(x, 0).lineTo(x, MAP_HEIGHT).stroke({ width: 1, color: MAP_GRID_COLOR }); } - // 100px 間隔横方向グリッド線 - for (let y = 0; y <= MAP_HEIGHT; y += 100) { - this.moveTo(0, y).lineTo(MAP_WIDTH, y).stroke({ width: 1, color: 0x333333 }); + // 横方向グリッド線 + for (let y = 0; y <= MAP_HEIGHT; y += GRID_CELL_SIZE) { + this.gridGraphics.moveTo(0, y).lineTo(MAP_WIDTH, y).stroke({ width: 1, color: MAP_GRID_COLOR }); } // プレイ領域外枠 - this.rect(0, 0, MAP_WIDTH, MAP_HEIGHT).stroke({ width: 5, color: 0xff4444 }); + this.gridGraphics.rect(0, 0, MAP_WIDTH, MAP_HEIGHT).stroke({ width: 5, color: MAP_BORDER_COLOR }); + } + + /** + * サーバー(またはテストロジック)から受け取った最新のマップ状態で色を更新する + */ + public updateMapState(state: MapState) { + const { GRID_CELL_SIZE, TEAM_COLORS } = GAME_CONFIG; + + for (let i = 0; i < state.gridColors.length; i++) { + const teamId = state.gridColors[i]; + const cell = this.cells[i]; + + // 一旦マスの描画をクリア + cell.clear(); + + // 塗布済み(-1以外)の場合のみ色を塗る + if (teamId !== -1) { + // Player.ts と同様に、文字列のカラーコードを PixiJS 用の数値に変換 + const colorString = TEAM_COLORS[teamId] || '#FFFFFF'; + const hexColor = parseInt(colorString.replace("#", "0x"), 16); + + // cell.x, cell.y は設定済みなので、ローカル座標 (0,0) からサイズ分を塗りつぶす + cell.rect(0, 0, GRID_CELL_SIZE, GRID_CELL_SIZE).fill(hexColor); + } + } } } \ No newline at end of file diff --git "a/docs/01_Env/ENV_01_\347\222\260\345\242\203\346\247\213\347\257\211\343\203\273\346\212\200\350\241\223\343\202\271\343\202\277\343\203\203\343\202\257.txt" "b/docs/01_Env/ENV_01_\347\222\260\345\242\203\346\247\213\347\257\211\343\203\273\346\212\200\350\241\223\343\202\271\343\202\277\343\203\203\343\202\257.txt" index 7ae9cd1..66d1fc0 100644 --- "a/docs/01_Env/ENV_01_\347\222\260\345\242\203\346\247\213\347\257\211\343\203\273\346\212\200\350\241\223\343\202\271\343\202\277\343\203\203\343\202\257.txt" +++ "b/docs/01_Env/ENV_01_\347\222\260\345\242\203\346\247\213\347\257\211\343\203\273\346\212\200\350\241\223\343\202\271\343\202\277\343\203\203\343\202\257.txt" @@ -68,7 +68,7 @@ ├── src/ │ ├── config/ # 共通定数(gameConfig.ts) │ ├── protocol/ # 通信イベント定義(events.ts) - │ ├── types/ # 型定義(payloads.ts, player.ts, room.ts) + │ ├── types/ # 型定義(map.ts, payloads.ts, player.ts, room.ts) │ └── index.ts # エントリーポイント (tsupビルド対象) ├── tsup.config.ts # ビルド設定 └── package.json diff --git a/packages/shared/src/config/gameConfig.ts b/packages/shared/src/config/gameConfig.ts index 88cad71..b2fbf6f 100644 --- a/packages/shared/src/config/gameConfig.ts +++ b/packages/shared/src/config/gameConfig.ts @@ -26,5 +26,10 @@ // チームカラー設定 // teamId インデックス順カラー配列 - TEAM_COLORS: ['#FF4B4B', '#4B4BFF', '#4BFF4B', '#FFD700'], + TEAM_COLORS: ['#FF4B4B', '#4B4BFF', '#4BFF4B', '#FFD700'], + + // マップ描画用のカラー設定 + MAP_BG_COLOR: 0x111111, // 何も塗っていないマス(背景)の色 + MAP_GRID_COLOR: 0x333333, // グリッド線の色 + MAP_BORDER_COLOR: 0xff4444, // プレイ領域外枠の色 } as const; \ No newline at end of file diff --git a/packages/shared/src/types/map.ts b/packages/shared/src/types/map.ts new file mode 100644 index 0000000..a603272 --- /dev/null +++ b/packages/shared/src/types/map.ts @@ -0,0 +1,3 @@ +export interface MapState { + gridColors: number[]; +} \ No newline at end of file