feat: 添加房间状态 Store
This commit is contained in:
@@ -1,2 +1,3 @@
|
|||||||
export * from './account.ts'
|
export * from './account.ts'
|
||||||
export * from './baseLayout.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