feat: 添加房间状态 Store
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
export * from './account.ts'
|
||||
export * from './baseLayout.ts'
|
||||
export * from './room.ts'
|
||||
|
||||
157
src/stores/modules/room.ts
Normal file
157
src/stores/modules/room.ts
Normal file
@@ -0,0 +1,157 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import type { RoomDetailResponse, RoomPlayerDetail, MoveItem, RoomStatus } from '@/api/modules/game'
|
||||
|
||||
export const useRoomStore = defineStore('room', () => {
|
||||
// ===== 房间基础信息 =====
|
||||
const roomId = ref<string>('')
|
||||
const roomName = ref<string>('')
|
||||
const gameId = ref<string>('')
|
||||
const gameIcon = ref<string>('')
|
||||
const gameName = ref<string>('')
|
||||
const maxPlayers = ref<number>(0)
|
||||
const mode = ref<string>('')
|
||||
const stakes = ref<number>(0)
|
||||
const status = ref<RoomStatus>('waiting')
|
||||
const creatorId = ref<string>('')
|
||||
const creatorName = ref<string>('')
|
||||
const allowSpectate = ref<boolean>(true)
|
||||
|
||||
// ===== 玩家信息 =====
|
||||
const players = ref<RoomPlayerDetail[]>([])
|
||||
/** 当前用户是否为房主 */
|
||||
const isOwner = computed(() => creatorId.value === currentUserId.value)
|
||||
|
||||
// ===== 对局状态 =====
|
||||
const boardState = ref<number[][]>([])
|
||||
const currentTurn = ref<string | null>(null)
|
||||
const moves = ref<MoveItem[]>([])
|
||||
const winner = ref<string | null>(null)
|
||||
const resultType = ref<string | null>(null)
|
||||
/** 是否对局中 */
|
||||
const isPlaying = computed(() => status.value === 'playing')
|
||||
/** 是否已结束 */
|
||||
const isFinished = computed(() => status.value === 'finished')
|
||||
|
||||
// ===== 聊天消息 =====
|
||||
interface ChatMessage {
|
||||
userId: string
|
||||
content: string
|
||||
timestamp: number
|
||||
}
|
||||
const messages = ref<ChatMessage[]>([])
|
||||
|
||||
// ===== 当前用户身份 =====
|
||||
const currentUserId = ref<string>('')
|
||||
/** 当前用户在房间中的身份:player(玩家)| spectator(观战者) */
|
||||
const myRole = ref<'player' | 'spectator'>('spectator')
|
||||
/** 当前用户是否为玩家 */
|
||||
const isPlayer = computed(() => myRole.value === 'player')
|
||||
|
||||
// ===== 求和状态 =====
|
||||
const drawRequested = ref<boolean>(false)
|
||||
const drawRequestFrom = ref<string | null>(null)
|
||||
|
||||
/**
|
||||
* 从房间详情 HTTP 响应初始化 Store
|
||||
* @param detail - 房间详情响应数据
|
||||
* @param userId - 当前用户 ID
|
||||
*/
|
||||
function initFromDetail(detail: RoomDetailResponse, userId: string) {
|
||||
roomId.value = detail.roomId
|
||||
roomName.value = detail.name
|
||||
gameId.value = detail.gameId
|
||||
gameIcon.value = detail.gameIcon
|
||||
gameName.value = detail.gameName
|
||||
maxPlayers.value = detail.maxPlayers
|
||||
mode.value = detail.mode
|
||||
stakes.value = detail.stakes
|
||||
status.value = detail.status
|
||||
creatorId.value = detail.creatorId
|
||||
creatorName.value = detail.creatorName
|
||||
allowSpectate.value = detail.allowSpectate
|
||||
players.value = detail.players
|
||||
currentUserId.value = userId
|
||||
boardState.value = detail.boardState ?? []
|
||||
currentTurn.value = detail.currentTurn ?? null
|
||||
moves.value = detail.moves ?? []
|
||||
|
||||
// 判定当前用户是玩家还是观战者
|
||||
const isPlayerInRoom = detail.players.some((p) => p.userId === userId)
|
||||
myRole.value = isPlayerInRoom ? 'player' : 'spectator'
|
||||
}
|
||||
|
||||
/** 更新棋盘状态(WS move 事件) */
|
||||
function applyMove(row: number, col: number, playerId: string, moveIndex: number) {
|
||||
moves.value.push({ moveIndex, playerId, row, col })
|
||||
if (!boardState.value[row]) {
|
||||
boardState.value[row] = []
|
||||
}
|
||||
// 判定棋子颜色:moveIndex 从 1 开始,奇数=黑方(1),偶数=白方(2)
|
||||
const stone = moveIndex % 2 === 1 ? 1 : 2
|
||||
boardState.value[row][col] = stone
|
||||
}
|
||||
|
||||
/** 更新当前轮次 */
|
||||
function setCurrentTurn(playerId: string | null) {
|
||||
currentTurn.value = playerId
|
||||
}
|
||||
|
||||
/** 添加聊天消息 */
|
||||
function addMessage(msg: ChatMessage) {
|
||||
messages.value.push(msg)
|
||||
}
|
||||
|
||||
/** 更新准备状态 */
|
||||
function updateReady(userId: string, ready: boolean) {
|
||||
const player = players.value.find((p) => p.userId === userId)
|
||||
if (player) {
|
||||
player.ready = ready
|
||||
}
|
||||
}
|
||||
|
||||
/** 玩家加入 */
|
||||
function addPlayer(player: RoomPlayerDetail) {
|
||||
if (!players.value.find((p) => p.userId === player.userId)) {
|
||||
players.value.push(player)
|
||||
}
|
||||
}
|
||||
|
||||
/** 玩家离开 */
|
||||
function removePlayer(userId: string) {
|
||||
players.value = players.value.filter((p) => p.userId !== userId)
|
||||
}
|
||||
|
||||
/** 对局结束 */
|
||||
function setGameOver(winnerId: string | null, type: string) {
|
||||
status.value = 'finished'
|
||||
winner.value = winnerId
|
||||
resultType.value = type
|
||||
}
|
||||
|
||||
/** 重置状态 */
|
||||
function reset() {
|
||||
roomId.value = ''
|
||||
players.value = []
|
||||
boardState.value = []
|
||||
currentTurn.value = null
|
||||
moves.value = []
|
||||
messages.value = []
|
||||
winner.value = null
|
||||
resultType.value = null
|
||||
drawRequested.value = false
|
||||
drawRequestFrom.value = null
|
||||
}
|
||||
|
||||
return {
|
||||
roomId, roomName, gameId, gameIcon, gameName,
|
||||
maxPlayers, mode, stakes, status, creatorId, creatorName, allowSpectate,
|
||||
players, isOwner, currentUserId, myRole, isPlayer,
|
||||
boardState, currentTurn, moves, winner, resultType,
|
||||
isPlaying, isFinished,
|
||||
messages,
|
||||
drawRequested, drawRequestFrom,
|
||||
initFromDetail, applyMove, setCurrentTurn, addMessage,
|
||||
updateReady, addPlayer, removePlayer, setGameOver, reset
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user