diff --git a/src/config/tileMap.ts b/src/config/tileMap.ts new file mode 100644 index 0000000..add231f --- /dev/null +++ b/src/config/tileMap.ts @@ -0,0 +1,111 @@ +// src/config/tileMap.ts + +export type Suit = 'W' | 'T' | 'B' + +export interface Tile { + id: number + suit: Suit + value: number +} + +export type TilePosition = 'bottom' + +const SUIT_INDEX_MAP: Record = { + W: 1, // 万 + T: 2, // 筒 + B: 3, // 条 +} + +/** + * 当前目录结构: + * /src/assets/images/tiles/bottom/p4b1_1.png + * /src/assets/images/tiles/bottom/p4b2_1.png + * /src/assets/images/tiles/bottom/p4b3_1.png + */ +function buildTileImageKey( + suit: Suit, + value: number, + position: TilePosition = 'bottom', +): string { + const suitIndex = SUIT_INDEX_MAP[suit] + return `/src/assets/images/tiles/${position}/p4b${suitIndex}_${value}.png` +} + +/** + * 通过 Vite 收集所有麻将牌资源 + */ +const tileImageModules = import.meta.glob( + '/src/assets/images/tiles/bottom/*.png', + { + eager: true, + import: 'default', + }, +) as Record + +/** + * 判断是否为合法花色 + */ +export function isValidSuit(suit: string): suit is Suit { + return suit === 'W' || suit === 'T' || suit === 'B' +} + +/** + * 判断是否为合法点数 + */ +export function isValidTileValue(value: number): boolean { + return Number.isInteger(value) && value >= 1 && value <= 9 +} + +/** + * 判断是否为合法牌 + */ +export function isValidTile(tile: { suit: string; value: number }): tile is Pick { + return isValidSuit(tile.suit) && isValidTileValue(tile.value) +} + +/** + * 根据花色 + 点数获取图片路径 + */ +export function getTileImageBySuitAndValue( + suit: Suit, + value: number, + position: TilePosition = 'bottom', +): string { + if (!isValidTileValue(value)) { + return '' + } + + const key = buildTileImageKey(suit, value, position) + return tileImageModules[key] || '' +} + +/** + * 根据 Tile 获取图片路径 + */ +export function getTileImage( + tile: Pick, + position: TilePosition = 'bottom', +): string { + if (!isValidTile(tile)) { + return '' + } + + const key = buildTileImageKey(tile.suit, tile.value, position) + return tileImageModules[key] || '' +} + +/** + * 获取全部基础牌 + */ +export function getAllTiles(): Array> { + const suits: Suit[] = ['W', 'T', 'B'] + const result: Array> = [] + + for (const suit of suits) { + for (let value = 1; value <= 9; value++) { + result.push({suit, value}) + } + } + + return result +} \ No newline at end of file diff --git a/src/views/ChengduGamePage.vue b/src/views/ChengduGamePage.vue index 9a2cec7..e514084 100644 --- a/src/views/ChengduGamePage.vue +++ b/src/views/ChengduGamePage.vue @@ -37,6 +37,7 @@ import {useGameStore} from '../store/gameStore' import {setActiveRoom, useActiveRoomState} from '../store' import type {PlayerState} from '../types/state' import type {Tile} from '../types/tile' +import {getTileImage} from "../config/tileMap.ts"; const gameStore = useGameStore() const activeRoom = useActiveRoomState() @@ -451,6 +452,7 @@ function handleRoomInfoResponse(message: unknown): void { const summary = asRecord(payload.summary) ?? asRecord(payload.room_summary) ?? null const publicState = asRecord(payload.public) ?? asRecord(payload.public_state) ?? null const privateState = asRecord(payload.private) ?? asRecord(payload.private_state) ?? null + console.log("server response payload: " + payload) const roomId = readString(summary ?? {}, 'room_id', 'roomId') || readString(publicState ?? {}, 'room_id', 'roomId') || @@ -1455,8 +1457,8 @@ onBeforeUnmount(() => { 开始游戏 -
+