refactor(game): 重构缺门花色处理逻辑并优化组件结构
- 移除硬编码的花色图标导入,改用动态加载方式 - 添加新的 flowerColorMap 配置文件统一管理缺门图标 - 引入 clearActiveRoom 函数用于清理活动房间状态 - 在游戏数据解析中添加缺失花色的读取函数 - 当房间数据为空时自动清理房间状态并跳转回大厅 - 统一玩家缺门花色数据处理逻辑 - 注释掉浮动状态显示区域以优化界面布局 - 调整CSS样式中缺门标记尺寸和旋转效果 - 在游戏存储模块中添加清除快照功能 - 重构座位玩家卡片组件中的花色图标计算逻辑 - 优化花色标签映射和归一化处理函数
This commit is contained in:
@@ -2,9 +2,6 @@
|
||||
import {computed, onBeforeUnmount, onMounted, ref} from 'vue'
|
||||
import {useRoute, useRouter} from 'vue-router'
|
||||
import deskImage from '../assets/images/desk/desk_01.png'
|
||||
import wanIcon from '../assets/images/flowerClolor/wan.png'
|
||||
import tongIcon from '../assets/images/flowerClolor/tong.png'
|
||||
import tiaoIcon from '../assets/images/flowerClolor/tiao.png'
|
||||
import robotIcon from '../assets/images/icons/robot.svg'
|
||||
import exitIcon from '../assets/images/icons/exit.svg'
|
||||
import '../assets/styles/room.css'
|
||||
@@ -30,7 +27,7 @@ import {wsClient} from '../ws/client'
|
||||
import {sendWsMessage} from '../ws/sender'
|
||||
import {buildWsUrl} from '../ws/url'
|
||||
import {useGameStore} from '../store/gameStore'
|
||||
import {setActiveRoom, useActiveRoomState} from '../store'
|
||||
import {clearActiveRoom, setActiveRoom, useActiveRoomState} from '../store'
|
||||
import type {MeldState, PlayerState} from '../types/state'
|
||||
import type {Tile} from '../types/tile'
|
||||
import {getTileImage as getBottomTileImage} from '../config/bottomTileMap.ts'
|
||||
@@ -449,6 +446,14 @@ function readBoolean(source: Record<string, unknown>, ...keys: string[]): boolea
|
||||
return null
|
||||
}
|
||||
|
||||
function readMissingSuit(source: Record<string, unknown> | null | undefined): string | null {
|
||||
if (!source) {
|
||||
return null
|
||||
}
|
||||
|
||||
return readString(source, 'missing_suit', 'MissingSuit', 'ding_que', 'dingQue', 'suit', 'Suit') || null
|
||||
}
|
||||
|
||||
function tileToText(tile: Tile): string {
|
||||
return `${tile.suit}${tile.value}`
|
||||
}
|
||||
@@ -601,6 +606,15 @@ function handleRoomInfoResponse(message: unknown): void {
|
||||
const room = asRecord(payload.room)
|
||||
const gameState = asRecord(payload.game_state)
|
||||
const playerView = asRecord(payload.player_view)
|
||||
|
||||
if (!room && !gameState && !playerView) {
|
||||
clearActiveRoom()
|
||||
gameStore.resetGame()
|
||||
wsClient.close()
|
||||
void router.push('/hall')
|
||||
return
|
||||
}
|
||||
|
||||
const roomId =
|
||||
readString(room ?? {}, 'room_id', 'roomId') ||
|
||||
readString(gameState ?? {}, 'room_id', 'roomId') ||
|
||||
@@ -657,7 +671,7 @@ function handleRoomInfoResponse(message: unknown): void {
|
||||
readString(player, 'player_name', 'PlayerName', 'display_name', 'displayName', 'nickname', 'username') ||
|
||||
(playerId === loggedInUserId.value ? loggedInUserName.value : '')
|
||||
const ready = readBoolean(player, 'ready', 'Ready') ?? false
|
||||
const missingSuit = readString(player, 'missing_suit', 'MissingSuit') || null
|
||||
const missingSuit = readMissingSuit(player)
|
||||
|
||||
playerMap.set(playerId, {
|
||||
roomPlayer: {
|
||||
@@ -705,7 +719,7 @@ function handleRoomInfoResponse(message: unknown): void {
|
||||
readNumber(player, 'index', 'Index', 'seat_index', 'seatIndex') ??
|
||||
fallbackIndex
|
||||
const displayName = existing?.gamePlayer.displayName || (playerId === loggedInUserId.value ? loggedInUserName.value : '')
|
||||
const missingSuit = readString(player, 'missing_suit', 'MissingSuit') || existing?.gamePlayer.missingSuit || null
|
||||
const missingSuit = readMissingSuit(player) || existing?.gamePlayer.missingSuit || null
|
||||
const handCount = readNumber(player, 'hand_count', 'handCount') ?? 0
|
||||
const outTiles = normalizeTiles(player.out_tiles ?? player.outTiles)
|
||||
const melds = normalizeMelds(
|
||||
@@ -749,9 +763,12 @@ function handleRoomInfoResponse(message: unknown): void {
|
||||
if (loggedInUserId.value && playerMap.has(loggedInUserId.value)) {
|
||||
const current = playerMap.get(loggedInUserId.value)
|
||||
if (current) {
|
||||
const selfMissingSuit = readMissingSuit(playerView)
|
||||
current.roomPlayer.hand = privateHand.map((tile) => tileToText(tile))
|
||||
current.roomPlayer.missingSuit = selfMissingSuit || current.roomPlayer.missingSuit
|
||||
current.gamePlayer.handTiles = privateHand
|
||||
current.gamePlayer.handCount = privateHand.length
|
||||
current.gamePlayer.missingSuit = selfMissingSuit || current.gamePlayer.missingSuit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1030,26 +1047,11 @@ const seatDecor = computed<Record<SeatKey, SeatPlayerCardModel>>(() => {
|
||||
return result
|
||||
})
|
||||
|
||||
const floatingMissingSuit = computed(() => {
|
||||
const suitMap: Record<string, string> = {
|
||||
万: wanIcon,
|
||||
筒: tongIcon,
|
||||
条: tiaoIcon,
|
||||
}
|
||||
|
||||
const topLabel = seatDecor.value.top?.missingSuitLabel ?? ''
|
||||
const leftLabel = seatDecor.value.left?.missingSuitLabel ?? ''
|
||||
const rightLabel = seatDecor.value.right?.missingSuitLabel ?? ''
|
||||
|
||||
return {
|
||||
top: suitMap[topLabel] ?? '',
|
||||
left: suitMap[leftLabel] ?? '',
|
||||
right: suitMap[rightLabel] ?? '',
|
||||
}
|
||||
})
|
||||
|
||||
function missingSuitLabel(value: string | null | undefined): string {
|
||||
const suitMap: Record<string, string> = {
|
||||
w: '万',
|
||||
t: '筒',
|
||||
b: '条',
|
||||
wan: '万',
|
||||
tong: '筒',
|
||||
tiao: '条',
|
||||
@@ -1058,7 +1060,9 @@ function missingSuitLabel(value: string | null | undefined): string {
|
||||
if (!value) {
|
||||
return ''
|
||||
}
|
||||
return suitMap[value] ?? value
|
||||
|
||||
const normalized = value.trim().toLowerCase()
|
||||
return suitMap[normalized] ?? value
|
||||
}
|
||||
|
||||
function toggleMenu(): void {
|
||||
@@ -1825,18 +1829,18 @@ onBeforeUnmount(() => {
|
||||
<span v-if="wallSeats.left.hasHu" class="wall-hu-flag">胡</span>
|
||||
</div>
|
||||
|
||||
<div class="floating-status top">
|
||||
<img v-if="floatingMissingSuit.top" :src="floatingMissingSuit.top" alt=""/>
|
||||
<span>{{ seatDecor.top.missingSuitLabel }}</span>
|
||||
</div>
|
||||
<div class="floating-status left">
|
||||
<img v-if="floatingMissingSuit.left" :src="floatingMissingSuit.left" alt=""/>
|
||||
<span>{{ seatDecor.left.missingSuitLabel }}</span>
|
||||
</div>
|
||||
<div class="floating-status right">
|
||||
<img v-if="floatingMissingSuit.right" :src="floatingMissingSuit.right" alt=""/>
|
||||
<span>{{ seatDecor.right.missingSuitLabel }}</span>
|
||||
</div>
|
||||
<!-- <div class="floating-status top">-->
|
||||
<!-- <img v-if="floatingMissingSuit.top" :src="floatingMissingSuit.top" alt=""/>-->
|
||||
<!-- <span>{{ seatDecor.top.missingSuitLabel }}</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="floating-status left">-->
|
||||
<!-- <img v-if="floatingMissingSuit.left" :src="floatingMissingSuit.left" alt=""/>-->
|
||||
<!-- <span>{{ seatDecor.left.missingSuitLabel }}</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="floating-status right">-->
|
||||
<!-- <img v-if="floatingMissingSuit.right" :src="floatingMissingSuit.right" alt=""/>-->
|
||||
<!-- <span>{{ seatDecor.right.missingSuitLabel }}</span>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<WindSquare class="center-wind-square" :seat-winds="seatWinds"/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user