From b1e394d675f60fd147cbcfdd6a8839cfcb67f115 Mon Sep 17 00:00:00 2001 From: wsy182 <2392948297@qq.com> Date: Fri, 27 Mar 2026 14:16:04 +0800 Subject: [PATCH] =?UTF-8?q?feat(game):=20=E6=B7=BB=E5=8A=A0=E9=BA=BB?= =?UTF-8?q?=E5=B0=86=E7=89=8C=E5=9B=BE=E7=89=87=E6=98=A0=E5=B0=84=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=B9=B6=E4=BC=98=E5=8C=96=E6=88=90=E9=83=BD=E9=BA=BB?= =?UTF-8?q?=E5=B0=86=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 tileMap.ts 配置文件,定义麻将牌图片映射逻辑 - 实现根据花色和点数获取对应图片路径的功能 - 添加麻将牌验证和基础牌生成工具函数 - 在 ChengduGamePage.vue 中导入并使用 getTileImage 函数 - 添加服务器响应日志用于调试 - 优化玩家手牌显示区域的布局结构 --- src/config/tileMap.ts | 111 ++++++++++++++++++++++++++++++++++ src/views/ChengduGamePage.vue | 4 +- 2 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 src/config/tileMap.ts 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(() => { 开始游戏 -
+