🎈 perf: 优化代码

This commit is contained in:
Litrix 2024-12-19 13:04:34 +08:00
parent 8d5a19248c
commit b8ddd0c254
3 changed files with 78 additions and 26 deletions

View File

@ -12,7 +12,7 @@ export interface PayloadPart<N extends string, P extends Payload = {}> extends S
payload: P;
}
type BaseResp = PayloadPart<string, Record<string, unknown>>;
type Relations<TRequestNames extends string, TRespNames extends string> = Partial<
export type Relations<TRequestNames extends string, TRespNames extends string> = Partial<
Record<TRequestNames, MaybeArray<TRespNames, true>>
>;
export interface UseGameSocketOptions<

View File

@ -14,7 +14,10 @@
v-loading="loading"
:element-loading-text="loadingText"
class="gobang-list-page-main flex-col"
:class="{ flex: !rooms.length, center: !rooms.length }"
:class="[
!rooms.length ? 'justify-center items-center' : undefined,
{ '!flex': !rooms.length },
]"
>
<template v-if="rooms.length || !loading">
<template v-if="!rooms.length">
@ -85,6 +88,16 @@ export type RoomDetail = {
whiteUser?: UserInfo;
blackUser?: UserInfo;
};
export enum WinFace {
UP = 'UP',
UP_RIGHT = 'UP_RIGHT',
RIGHT = 'RIGHT',
DOWN_RIGHT = 'DOWN_RIGHT',
DOWN = 'DOWN',
DOWN_LEFT = 'DOWN_LEFT',
LEFT = 'LEFT',
UP_LEFT = 'UP_LEFT',
}
export type Request =
| SimplePart<'RoomList'>
| SimplePart<'CreateRoom'>
@ -98,13 +111,24 @@ export type Resp =
| PayloadPart<'PlayerSideAllocation', { isWhite: boolean }>
| PayloadPart<'RoomInfo', RoomDetail>
| PayloadPart<'PlayerJoinRoom', { room: Room; user: UserInfo }>
| PayloadPart<'PlayerLeave'>;
export const relations = {
| PayloadPart<'PlayerLeave'>
| PayloadPart<
'HasPlayerWin',
{
face: WinFace;
isWhite: boolean;
originalX: number;
originalY: number;
}
>
| PayloadPart<'PlayerWin'>
| PayloadPart<'PlayerLose'>;
const relations = {
RoomList: 'RoomList',
CreateRoom: 'RoomCreated',
PlayerJoin: ['PlayerSideAllocation', 'RoomInfo'],
PlaceChessPiece: ['RoomInfo'],
} as const;
} as const satisfies Relations<Request['name'], Resp['name']>;
export function useGobangSocket(
options: Omit<UseGameSocketOptions<Request, Resp, typeof relations>, 'url' | 'relations'>,
) {
@ -125,6 +149,7 @@ import { useUserStore } from '@/stores/user';
import {
useGameSocket,
type PayloadPart,
type Relations,
type SimplePart,
type UseGameSocketOptions,
} from '@/utils/game-socket';

View File

@ -66,7 +66,7 @@
</div>
<div class="flex flex-col items-center">
<gobang-user v-if="userStore.userInfo" :user="userStore.userInfo" />
<div class="font-bold text-5">
<div v-if="otherUser" class="font-bold text-5">
<template v-if="selfRound">请落子.</template>
<template v-else>等待对方落子.</template>
</div>
@ -125,21 +125,7 @@
}
}
</style>
<script setup lang="ts">
import GobangHeader from '@/components/gobang/GobangHeader.vue';
import GobangUser from '@/components/gobang/GobangUser.vue';
import router from '@/router';
import { useMediaStore } from '@/stores/media';
import { useUserStore } from '@/stores/user';
import { useGobangSocket, type RoomDetail, type RoomId } from '@/views/GobangListPage.vue';
import { ElMessage } from 'element-plus';
import { storeToRefs } from 'pinia';
import { computed, onMounted, ref, watch, watchEffect, type CSSProperties } from 'vue';
import { useRoute } from 'vue-router';
const userStore = useUserStore();
const { smLess, mdLess } = storeToRefs(useMediaStore());
const roomId = useRoute().params.id as RoomId | undefined;
const canvas = ref<HTMLCanvasElement>();
<script lang="ts">
const boardBackground = '#E2CFA9';
const boardLength = 16;
const gridSize = 30;
@ -149,6 +135,33 @@ const boardOuterBorderSize = 2;
/** 棋盘外边框+内边框总大小 */
const boardBorderSize = 5;
const boardPadding = 15;
const deltaMap: Record<WinFace, [number, number]> = {
[WinFace.UP]: [0, -1],
[WinFace.UP_RIGHT]: [1, -1],
[WinFace.RIGHT]: [1, 0],
[WinFace.DOWN_RIGHT]: [1, 1],
[WinFace.DOWN]: [0, 1],
[WinFace.DOWN_LEFT]: [-1, 1],
[WinFace.LEFT]: [-1, 0],
[WinFace.UP_LEFT]: [-1, -1],
};
</script>
<script setup lang="ts">
import GobangHeader from '@/components/gobang/GobangHeader.vue';
import GobangUser from '@/components/gobang/GobangUser.vue';
import router from '@/router';
import { useMediaStore } from '@/stores/media';
import { useUserStore } from '@/stores/user';
import { create2DArray } from '@/utils';
import { useGobangSocket, WinFace, type RoomDetail, type RoomId } from '@/views/GobangListPage.vue';
import { ElMessage } from 'element-plus';
import { storeToRefs } from 'pinia';
import { computed, onMounted, ref, watch, watchEffect, type CSSProperties } from 'vue';
import { useRoute } from 'vue-router';
const userStore = useUserStore();
const { smLess, mdLess } = storeToRefs(useMediaStore());
const roomId = useRoute().params.id as RoomId | undefined;
const canvas = ref<HTMLCanvasElement>();
/** 棋盘大小 */
const boardSize = computed(
() => gridSize * (boardLength - 1) + boardBorderSize * 2 + boardPadding * 2,
@ -237,6 +250,9 @@ watch(matchState, (v) => {
});
const placing = ref(false);
const selfRound = ref(false);
function resetSelfRound() {
selfRound.value = !isWhite.value;
}
const enabled = computed(
() => matchState.value === MatchState.GAMING && selfRound.value && !placing.value,
);
@ -253,10 +269,12 @@ watch(otherUser, (v, old) => {
updateMatchState();
});
const grid = computed<Grid | undefined>(() =>
room.value?.pieces.map((row) =>
row.map((v) => (v === 0 ? { isWhite: false } : v === 1 ? { isWhite: true } : undefined)),
),
room.value?.pieces.map((row) => row.map((v) => (v !== -1 ? { isWhite: !!v } : undefined))),
);
const blink = ref<boolean[][]>([]);
function resetBlink() {
blink.value = create2DArray(boardLength, boardLength, false);
}
const isWhite = ref(false);
function onCellClick(cell: Chess | undefined, x: number, y: number) {
if (cell || !enabled.value) return;
@ -278,8 +296,8 @@ const { send } = useGobangSocket({
});
},
PlayerSideAllocation(p) {
console.log(p.isWhite);
selfRound.value = !(isWhite.value = p.isWhite);
isWhite.value = p.isWhite;
resetSelfRound();
},
RoomInfo(p) {
room.value = p;
@ -290,7 +308,11 @@ const { send } = useGobangSocket({
PlayerLeave() {
ElMessage.warning('对方已离开房间,对局自动结束');
room.value = undefined;
resetSelfRound();
resetRoom();
resetBlink();
},
HasPlayerWin() {},
},
error: {
PlayerJoin() {
@ -310,6 +332,11 @@ const { send } = useGobangSocket({
},
},
});
function resetRoom() {
send({
name: 'ResetRoom',
});
}
onMounted(() => {
if (!roomId) {
matchState.value = MatchState.GAMING;