feat(game): 实现出牌选择与计时功能
- 添加 PlayerTurnPayload 接口定义和 PLAYER_TURN 动作类型 - 实现选牌、出牌确认逻辑和相关状态管理 - 添加客户端出牌限制检查和错误提示 - 集成 PLAYER_TURN WebSocket 消息处理 - 添加房间状态面板显示游戏信息 - 优化桌面背景图片和样式布局 - 添加马蹄形动画样式文件 - 配置 Vite 别名和端口设置
This commit is contained in:
@@ -4,7 +4,8 @@ import {
|
||||
type GameState,
|
||||
type PendingClaimState,
|
||||
} from '../types/state'
|
||||
import type { RoomPlayerUpdatePayload, RoomTrusteePayload } from '../game/actions'
|
||||
import type { PlayerTurnPayload, RoomPlayerUpdatePayload, RoomTrusteePayload } from '../game/actions'
|
||||
import { readStoredAuth } from '../utils/auth-storage'
|
||||
|
||||
import type { Tile } from '../types/tile'
|
||||
|
||||
@@ -16,6 +17,7 @@ export const useGameStore = defineStore('game', {
|
||||
|
||||
dealerIndex: 0,
|
||||
currentTurn: 0,
|
||||
currentPlayerId: '',
|
||||
needDraw: false,
|
||||
|
||||
players: {},
|
||||
@@ -34,7 +36,7 @@ export const useGameStore = defineStore('game', {
|
||||
this.$reset()
|
||||
},
|
||||
|
||||
// 初始化
|
||||
// 初始<EFBFBD>?
|
||||
initGame(data: GameState) {
|
||||
Object.assign(this, data)
|
||||
},
|
||||
@@ -53,8 +55,9 @@ export const useGameStore = defineStore('game', {
|
||||
// 剩余牌数减少
|
||||
this.remainingTiles = Math.max(0, this.remainingTiles - 1)
|
||||
|
||||
// 更新回合(seatIndex)
|
||||
// 更新回合(seatIndex<EFBFBD>?
|
||||
this.currentTurn = player.seatIndex
|
||||
this.currentPlayerId = player.playerId
|
||||
|
||||
// 清除操作窗口
|
||||
this.pendingClaim = undefined
|
||||
@@ -84,7 +87,7 @@ export const useGameStore = defineStore('game', {
|
||||
}
|
||||
player.handCount = Math.max(0, player.handCount - 1)
|
||||
|
||||
// 加入出牌区
|
||||
// 加入出牌<EFBFBD>?
|
||||
player.discardTiles.push(data.tile)
|
||||
|
||||
// 更新回合
|
||||
@@ -95,7 +98,7 @@ export const useGameStore = defineStore('game', {
|
||||
this.phase = GAME_PHASE.ACTION
|
||||
},
|
||||
|
||||
// 触发操作窗口(碰/杠/胡)
|
||||
// 触发操作窗口(碰/<EFBFBD>?胡)
|
||||
onPendingClaim(data: PendingClaimState) {
|
||||
this.pendingClaim = data
|
||||
this.needDraw = false
|
||||
@@ -220,14 +223,49 @@ export const useGameStore = defineStore('game', {
|
||||
},
|
||||
|
||||
// 清理操作窗口
|
||||
onPlayerTurn(payload: PlayerTurnPayload) {
|
||||
const playerId =
|
||||
(typeof payload.player_id === 'string' && payload.player_id) ||
|
||||
(typeof payload.playerId === 'string' && payload.playerId) ||
|
||||
(typeof payload.PlayerID === 'string' && payload.PlayerID) ||
|
||||
''
|
||||
if (!playerId) {
|
||||
return
|
||||
}
|
||||
|
||||
const player = this.players[playerId]
|
||||
if (player) {
|
||||
this.currentTurn = player.seatIndex
|
||||
}
|
||||
this.currentPlayerId = playerId
|
||||
|
||||
this.needDraw = false
|
||||
this.pendingClaim = undefined
|
||||
this.phase = GAME_PHASE.PLAYING
|
||||
},
|
||||
|
||||
clearPendingClaim() {
|
||||
this.pendingClaim = undefined
|
||||
this.phase = GAME_PHASE.PLAYING
|
||||
},
|
||||
|
||||
// 获取当前玩家ID(后续建议放到 userStore)
|
||||
// 获取当前玩家ID(后续建议放<EFBFBD>?userStore<EFBFBD>?
|
||||
getMyPlayerId(): string {
|
||||
return Object.keys(this.players)[0] || ''
|
||||
const auth = readStoredAuth()
|
||||
const source = auth?.user as Record<string, unknown> | undefined
|
||||
const rawId =
|
||||
source?.id ??
|
||||
source?.userID ??
|
||||
source?.user_id
|
||||
if (typeof rawId === 'string' && rawId.trim()) {
|
||||
return rawId
|
||||
}
|
||||
if (typeof rawId === 'number') {
|
||||
return String(rawId)
|
||||
}
|
||||
return ''
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user