diff --git a/packages/Chinese-chess/components.d.ts b/packages/Chinese-chess/components.d.ts index 1a73a7c..c69fb97 100644 --- a/packages/Chinese-chess/components.d.ts +++ b/packages/Chinese-chess/components.d.ts @@ -7,7 +7,10 @@ export {} declare module '@vue/runtime-core' { export interface GlobalComponents { + ABadge: typeof import('ant-design-vue/es')['Badge'] AButton: typeof import('ant-design-vue/es')['Button'] + AInput: typeof import('ant-design-vue/es')['Input'] + AInputGroup: typeof import('ant-design-vue/es')['InputGroup'] ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup'] ASpin: typeof import('ant-design-vue/es')['Spin'] CampSeat: typeof import('./src/components/ChessMain/CampSeat.vue')['default'] @@ -19,6 +22,7 @@ declare module '@vue/runtime-core' { LeftOutlined: typeof import('@ant-design/icons-vue')['LeftOutlined'] Modal: typeof import('./src/components/Message/Modal.vue')['default'] ModeSelector: typeof import('./src/components/ModeSelector.vue')['default'] + SoundOutlined: typeof import('@ant-design/icons-vue')['SoundOutlined'] Spectator: typeof import('./src/components/ChessMain/Spectator.vue')['default'] StatusWrapper: typeof import('./src/components/ChessMain/StatusWrapper.vue')['default'] } diff --git a/packages/Chinese-chess/package.json b/packages/Chinese-chess/package.json index beaebb6..8696f2a 100644 --- a/packages/Chinese-chess/package.json +++ b/packages/Chinese-chess/package.json @@ -23,7 +23,7 @@ "@ant-design/icons-vue": "^6.1.0", "@vitejs/plugin-vue": "^4.5.2", "ant-design-vue": "^3.2.15", - "chinese-chess-service": "^0.0.24", + "chinese-chess-service": "^0.0.25", "lodash.clonedeep": "^4.5.0", "socket.io-client": "^4.7.2", "vue": "^3.2.41" diff --git a/packages/Chinese-chess/public/fzlsft.ttf b/packages/Chinese-chess/public/fzlsft.ttf deleted file mode 100644 index 17d0885..0000000 Binary files a/packages/Chinese-chess/public/fzlsft.ttf and /dev/null differ diff --git a/packages/Chinese-chess/src/assets/resources/FZLSFT.ttf b/packages/Chinese-chess/public/resources/FZLSFT.ttf similarity index 100% rename from packages/Chinese-chess/src/assets/resources/FZLSFT.ttf rename to packages/Chinese-chess/public/resources/FZLSFT.ttf diff --git a/packages/Chinese-chess/public/STXINGKAI.ttf b/packages/Chinese-chess/public/resources/STXINGKAI.ttf similarity index 100% rename from packages/Chinese-chess/public/STXINGKAI.ttf rename to packages/Chinese-chess/public/resources/STXINGKAI.ttf diff --git a/packages/Chinese-chess/public/sword.png b/packages/Chinese-chess/public/resources/sword.png similarity index 100% rename from packages/Chinese-chess/public/sword.png rename to packages/Chinese-chess/public/resources/sword.png diff --git a/packages/Chinese-chess/public/win.png b/packages/Chinese-chess/public/resources/win.png similarity index 100% rename from packages/Chinese-chess/public/win.png rename to packages/Chinese-chess/public/resources/win.png diff --git a/packages/Chinese-chess/src/App.vue b/packages/Chinese-chess/src/App.vue index 79fc9d0..c5b7435 100644 --- a/packages/Chinese-chess/src/App.vue +++ b/packages/Chinese-chess/src/App.vue @@ -1,5 +1,6 @@ @@ -58,7 +85,8 @@ import events from '@/definitions/events' import { Room } from '@/types' import { createGameInterface, GameStatus, Camp, type GameContext, type UserLike } from 'chinese-chess-service' import { Socket } from 'socket.io-client' -import { message } from 'ant-design-vue' +import { Modal, message } from 'ant-design-vue' +import GameAside from './GameAside.vue' defineProps<{ handleRoomLeave: (roomId?: number | string) => void @@ -76,6 +104,8 @@ const gameMainRef = ref(null) const gameInterface = ref | null>(null) +const manual = computed(() => context.value?.manual ?? []) + onMounted(async () => { if (gameMainRef.value) { gameInterface.value = createGameInterface(resources) @@ -203,7 +233,7 @@ const handleContextChange = (context: GameContext, gameInterface: ReturnType { } } -// const handleSwitchCamp = () => { -// if (socket.value && currentUser.value && currentRoom.value) { -// socket.value.emit(events.room.seatRequest, { -// userId: currentUser.value.id, -// roomId: currentRoom.value.id -// }) -// } -// } +const handleSwitchCamp = () => { + if (socket.value && currentUser.value && currentRoom.value) { + socket.value.emit(events.room.seatRequest, { + userId: currentUser.value.id, + roomId: currentRoom.value.id + }) + } +} + +const handleRequestUndo = () => { + Modal.confirm({ + title: '提示', + content: '确定要悔棋吗?好丢人的哦~', + onOk: () => { + if (socket.value && currentUser.value && currentRoom.value) { + socket.value.emit(events.game.undoRequest, { + userId: currentUser.value.id, + roomId: currentRoom.value.id + }) + } + } + }) +} + +const handleGiveUp = () => { + Modal.confirm({ + title: '提示', + content: '确定要投降?好丢人的哦~', + onOk: () => { + if (socket.value && currentUser.value && currentRoom.value) { + socket.value.emit(events.game.giveUp, { + userId: currentUser.value.id, + roomId: currentRoom.value.id + }) + } + } + }) +} + +const handleChat = (content: string) => { + if (socket.value && currentUser.value && currentRoom.value) { + socket.value.emit(events.room.chat, { + userId: currentUser.value.id, + roomId: currentRoom.value.id, + content + }) + } +} provide('context', context) +provide('manual', manual) diff --git a/packages/Chinese-chess/src/pages/OnlineGame/index.vue b/packages/Chinese-chess/src/pages/OnlineGame/index.vue index c4f4394..af1634a 100644 --- a/packages/Chinese-chess/src/pages/OnlineGame/index.vue +++ b/packages/Chinese-chess/src/pages/OnlineGame/index.vue @@ -18,22 +18,20 @@ import useSocket from '@/composables/useSocket' import { Socket } from 'socket.io-client' import events from '@/definitions/events' import { USER_INFO_KEY } from '@/definitions' -import { Room, User } from '@/types' +import { ChatInfo, Room, User } from '@/types' import { Modal, message } from 'ant-design-vue' import GameLobby from './GameLobby.vue' import GameMain from './GameMain.vue' const emits = defineEmits<(e: 'update:mode', value: null) => void>() -// const GameLobby = defineAsyncComponent(() => import('./GameLobby.vue')) -// const GameMain = defineAsyncComponent(() => import('./GameMain.vue')) - const socket = useSocket() const rooms = ref([]) const currentUser = ref(JSON.parse(localStorage.getItem(USER_INFO_KEY) ?? 'null')) const currentRoom = ref(null) const context = ref(null) +const chatList = ref([]) onMounted(() => { if (!socket.value) { @@ -100,6 +98,7 @@ const socketHandler = (socket: Socket) => { currentRoom.value = null context.value = null + chatList.value.length = 0 } else { context.value = data } @@ -110,6 +109,7 @@ const socketHandler = (socket: Socket) => { }) socket.on(events.room.offline, (user, data) => { + message.destroy() message.info(`用户${user.nickname + ''}掉线了`) context.value = data @@ -123,45 +123,95 @@ const socketHandler = (socket: Socket) => { // message.value = msg }) - socket.on(events.room.seatRequest, (user: User) => { - // $.Message.open({ - // type: 'confirm', - // // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - // content: `用户「${user.nickname}」申请更换阵营`, - // onConfirm: () => { - // socket!.emit(events.room.seatResponse, { - // roomId: currentRoom.value!.id, - // user: currentUser.value!, - // isAgree: true - // }) - // }, - // onCancel: () => { - // socket!.emit(events.room.seatResponse, { - // roomId: currentRoom.value!.id, - // user: currentUser.value!, - // isAgree: false - // }) - // } - // }) - }) - - socket.on(events.room.seatResponse, agree => { - // $.Message.open({ - // type: 'message', - // content: `对方${agree ? '同意' : '拒绝'}更换阵营` - // }) - }) - - socket.on(events.game.start, () => { - // socket.emit(events.game.start, { - // roomId: currentRoom.value!.id, - // chessPieces: initChessPieces() - // }) + socket.on(events.room.seatRequest, () => { + Modal.destroyAll() + Modal.confirm({ + title: '提示', + content: '对方申请更换阵营,是否同意?', + onOk: () => { + socket.emit(events.room.seatResponse, { + userId: currentUser.value!.id, + roomId: currentRoom.value!.id, + isAgree: true + }) + }, + onCancel: () => { + socket.emit(events.room.seatResponse, { + userId: currentUser.value!.id, + roomId: currentRoom.value!.id, + isAgree: false + }) + } + }) + }) + + socket.on(events.room.seatResponse, (user, data, isAgree) => { + message.destroy() + if (currentUser.value?.id === user.id) { + message.info(`对方${isAgree ? '同意' : '拒绝'}更换阵营`) + } + context.value = data + }) + + socket.on(events.game.undoRequest, () => { + Modal.destroyAll() + Modal.confirm({ + title: '提示', + content: '对方申请悔棋,是否同意?', + onOk: () => { + socket.emit(events.game.undoResponse, { + userId: currentUser.value!.id, + roomId: currentRoom.value!.id, + isAgree: true + }) + }, + onCancel: () => { + socket.emit(events.game.undoResponse, { + userId: currentUser.value!.id, + roomId: currentRoom.value!.id, + isAgree: false + }) + } + }) + }) + + socket.on(events.game.undoResponse, (user, data, isAgree) => { + message.destroy() + if (currentUser.value?.id === user.id) { + message.info(`对方${isAgree ? '同意' : '拒绝'}悔棋`) + } + message.info(`用户「${user.nickname + ''}」悔棋了!!!!!!!!!!!!!`) + context.value = data + }) + + socket.on(events.game.giveUp, data => { + context.value = data + }) + + socket.on(events.game.start, (data) => { + message.destroy() + message.info('游戏开始') + context.value = data + }) + + socket.on(events.game.over, (data) => { + message.destroy() + message.info('游戏结束') + context.value = data + }) + + socket.on(events.room.chat, (chatInfo: ChatInfo) => { + chatList.value.push(chatInfo) + }) + + socket.on(events.error.roomMax, () => { + message.destroy() + message.info('当前房间容纳人数已满,去其他房间逛逛吧~') }) }) socket.on(events.client.disconnect, (userInfo: User) => { - console.log('88') + message.destroy() message.error('服务器连接中断,88') }) } @@ -189,4 +239,5 @@ provide('rooms', rooms) provide('currentRoom', currentRoom) provide('currentUser', currentUser) provide('context', context) +provide('chatList', chatList) diff --git a/packages/Chinese-chess/src/types/index.d.ts b/packages/Chinese-chess/src/types/index.d.ts index 69527fc..c37cc36 100644 --- a/packages/Chinese-chess/src/types/index.d.ts +++ b/packages/Chinese-chess/src/types/index.d.ts @@ -14,16 +14,8 @@ export interface Room { id: string name: string users: User[] - context: GameContext -} - -export interface Message { - id: string - roomId: Room['id'] - user: User - type: MessageType - msg: string - createdTime: number + limit: number + status: GameStatus } export interface ChessManual { @@ -61,3 +53,11 @@ export interface GameContext { animations: GameAnimation[] } + +export interface ChatInfo { + content: string + userId: string + nickname: string + roomId: string + createdTime: number +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 985c0b2..0bb53d4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,8 +106,8 @@ importers: specifier: ^3.2.15 version: 3.2.15(vue@3.2.45) chinese-chess-service: - specifier: ^0.0.24 - version: 0.0.24 + specifier: ^0.0.25 + version: 0.0.25 lodash.clonedeep: specifier: ^4.5.0 version: 4.5.0 @@ -1545,8 +1545,8 @@ packages: resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} dev: true - /chinese-chess-service@0.0.24: - resolution: {integrity: sha512-+pmV0H6Fypg806m11HxNF4KgIh+Esr6KZWV4NUjURdt8KWd6g+Ic3xk6zPsrFesGFuBzyfuSrkm1PBxBYCNK2A==} + /chinese-chess-service@0.0.25: + resolution: {integrity: sha512-DfUI++UmO0NbXWAe2q+fONBouxnszjR6xGhpzj7CBLqxvaBVdnvbq8riXY7No/uykL+8A6/4XQDh8Ef9LicQOQ==} dependencies: mitt: 3.0.1 dev: false