From 8ef64f8f42aca61c0b6201f0e75daf211d527aa2 Mon Sep 17 00:00:00 2001 From: linyimin <18316471919@139.com> Date: Tue, 26 May 2026 11:43:35 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat=EF=BC=9A=E6=AF=94=E8=B5=9B=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/audioManager.js | 53 +- src/components/BackToGame.vue | 2 +- src/components/Container.vue | 2 +- src/components/Header.vue | 8 +- src/components/TeamAvatars.vue | 54 +- src/pages.json | 2 +- src/pages/battle-room.vue | 2 +- src/pages/friend-battle-result.vue | 4 +- src/pages/match-page.vue | 6 +- .../team-battle/components/AppBackground.vue | 91 ++ src/pages/team-battle/components/Avatar.vue | 123 ++ .../team-battle/components/BackToGame.vue | 138 ++ .../team-battle/components/BattleFooter.vue | 203 +++ .../team-battle/components/BattleHeader.vue | 200 +++ src/pages/team-battle/components/BowPower.vue | 40 + .../team-battle/components/BowTarget.vue | 451 ++++++ .../team-battle/components/Container.vue | 353 +++++ src/pages/team-battle/components/Guide.vue | 60 + src/pages/team-battle/components/Header.vue | 328 +++++ .../team-battle/components/HeaderProgress.vue | 83 ++ .../team-battle/components/IconButton.vue | 39 + .../team-battle/components/PointSwitcher.vue | 71 + .../team-battle/components/RoundEndTip.vue | 172 +++ src/pages/team-battle/components/SButton.vue | 96 ++ src/pages/team-battle/components/SModal.vue | 108 ++ .../team-battle/components/ScreenHint.vue | 89 ++ .../team-battle/components/ShootProgress2.vue | 215 +++ .../team-battle/components/TeamAvatars.vue | 150 ++ .../team-battle/components/TestDistance.vue | 193 +++ src/pages/team-battle/index.vue | 1277 +++++++++++++++++ 30 files changed, 4575 insertions(+), 38 deletions(-) create mode 100644 src/pages/team-battle/components/AppBackground.vue create mode 100644 src/pages/team-battle/components/Avatar.vue create mode 100644 src/pages/team-battle/components/BackToGame.vue create mode 100644 src/pages/team-battle/components/BattleFooter.vue create mode 100644 src/pages/team-battle/components/BattleHeader.vue create mode 100644 src/pages/team-battle/components/BowPower.vue create mode 100644 src/pages/team-battle/components/BowTarget.vue create mode 100644 src/pages/team-battle/components/Container.vue create mode 100644 src/pages/team-battle/components/Guide.vue create mode 100644 src/pages/team-battle/components/Header.vue create mode 100644 src/pages/team-battle/components/HeaderProgress.vue create mode 100644 src/pages/team-battle/components/IconButton.vue create mode 100644 src/pages/team-battle/components/PointSwitcher.vue create mode 100644 src/pages/team-battle/components/RoundEndTip.vue create mode 100644 src/pages/team-battle/components/SButton.vue create mode 100644 src/pages/team-battle/components/SModal.vue create mode 100644 src/pages/team-battle/components/ScreenHint.vue create mode 100644 src/pages/team-battle/components/ShootProgress2.vue create mode 100644 src/pages/team-battle/components/TeamAvatars.vue create mode 100644 src/pages/team-battle/components/TestDistance.vue create mode 100644 src/pages/team-battle/index.vue diff --git a/src/audioManager.js b/src/audioManager.js index 44fe3a5..a0f55bb 100644 --- a/src/audioManager.js +++ b/src/audioManager.js @@ -1,3 +1,6 @@ +export const AUDIO_INTERRUPTION_BEGIN_EVENT = "audio-interruption-begin"; +export const AUDIO_INTERRUPTION_END_EVENT = "audio-interruption-end"; + export const audioFils = { tententen: "https://static.shelingxingqiu.com/shootmini/static/audio/tententen.mp3", 点击按钮: "https://static.shelingxingqiu.com/shootmini/static/audio/%E7%82%B9%E5%87%BB%E6%8C%89%E9%92%AE.mp3", @@ -97,7 +100,7 @@ function debugLog(...args) { const envVersion = accountInfo.miniProgram.envVersion; // 只在体验版打印日志,正式版(release)和开发版(develop)不打印 - if (envVersion === "trial") { + if (envVersion === "trial" || envVersion === "develop") { console.log(...args); } } @@ -127,6 +130,7 @@ class AudioManager { // 防重复播放保护 this.lastPlayKey = null; this.lastPlayAt = 0; + this.isInterrupted = false; // 静音开关 this.isMuted = false; @@ -141,10 +145,41 @@ class AudioManager { this.localFileCache = uni.getStorageSync("audio_local_files") || {}; // 启动时自动清理过期的缓存文件(URL 已不在 audioFils 中的文件) this.cleanObsoleteCache(); + this.bindAudioInterruptionEvents(); this.initAudios(); } + bindAudioInterruptionEvents() { + if (this._audioInterruptionBound) return; + this._audioInterruptionBound = true; + + const begin = () => { + if (this.isInterrupted) return; + this.isInterrupted = true; + this.stopAll(); + this.isSequenceRunning = false; + this.sequenceQueue = []; + this.sequenceIndex = 0; + this.pendingPlayKey = null; + uni.$emit(AUDIO_INTERRUPTION_BEGIN_EVENT); + }; + + const end = () => { + if (!this.isInterrupted) return; + this.isInterrupted = false; + uni.$emit(AUDIO_INTERRUPTION_END_EVENT); + void this.reloadAll(); + }; + + if (typeof uni?.onAudioInterruptionBegin === "function") { + uni.onAudioInterruptionBegin(begin); + } + if (typeof uni?.onAudioInterruptionEnd === "function") { + uni.onAudioInterruptionEnd(end); + } + } + // 清理不再使用的缓存文件 cleanObsoleteCache() { const activeUrls = new Set(Object.values(audioFils)); @@ -461,6 +496,10 @@ class AudioManager { // 播放指定音频或音频数组(数组则按顺序连续播放) play(input, interrupt = true) { + if (this.isInterrupted) { + debugLog("音频处理中断状态,忽略播放请求"); + return; + } // 统一规范化为队列 let queue = []; if (Array.isArray(input)) { @@ -514,6 +553,10 @@ class AudioManager { // 内部方法:播放单个 key _playSingle(key, forceStopAll = false) { + if (this.isInterrupted) { + debugLog(`音频处理中断状态,跳过播放: ${key}`); + return; + } // 200ms 内的同 key 重复播放直接忽略,避免“比比赛开始”这类重复首音 const now = Date.now(); if (this.lastPlayKey === key && now - this.lastPlayAt < 250) { @@ -557,7 +600,13 @@ class AudioManager { // 显式授权播放并立即播放 this.allowPlayMap.set(key, true); - audio.play(); + try { + audio.play(); + } catch (err) { + this.allowPlayMap.set(key, false); + debugLog(`音频 ${key} 播放调用失败`, err?.errMsg || err); + return; + } this.currentPlayingKey = key; this.lastPlayKey = key; this.lastPlayAt = Date.now(); diff --git a/src/components/BackToGame.vue b/src/components/BackToGame.vue index 43057af..b5a509c 100644 --- a/src/components/BackToGame.vue +++ b/src/components/BackToGame.vue @@ -54,7 +54,7 @@ const onClick = debounce(async () => { await uni.$checkAudio(); if (result.mode <= 3) { uni.navigateTo({ - url: `/pages/team-battle?battleId=${result.matchId}`, + url: `/pages/team-battle/index?battleId=${result.matchId}`, }); } else { uni.navigateTo({ diff --git a/src/components/Container.vue b/src/components/Container.vue index 280959c..36840f2 100644 --- a/src/components/Container.vue +++ b/src/components/Container.vue @@ -116,7 +116,7 @@ const backToGame = debounce(async () => { await checkAudioProgress(); if (result.mode <= 3) { uni.navigateTo({ - url: `/pages/team-battle?battleId=${result.matchId}`, + url: `/pages/team-battle/index?battleId=${result.matchId}`, }); } else { uni.navigateTo({ diff --git a/src/components/Header.vue b/src/components/Header.vue index 828b0a8..8dadfcd 100644 --- a/src/components/Header.vue +++ b/src/components/Header.vue @@ -185,7 +185,13 @@ onBeforeUnmount(() => { }} - + diff --git a/src/components/TeamAvatars.vue b/src/components/TeamAvatars.vue index 37bd8c8..8a41949 100644 --- a/src/components/TeamAvatars.vue +++ b/src/components/TeamAvatars.vue @@ -1,5 +1,5 @@ @@ -70,7 +74,7 @@ watch( /> 3 为大乱斗,覆盖全部 gameType(1~5),不再遗漏 if (msg.mode <= 3) { uni.redirectTo({ - url: `/pages/team-battle?battleId=${msg.id}`, + url: `/pages/team-battle/index?battleId=${msg.id}`, }); } else { uni.redirectTo({ diff --git a/src/pages/team-battle/components/AppBackground.vue b/src/pages/team-battle/components/AppBackground.vue new file mode 100644 index 0000000..134b66e --- /dev/null +++ b/src/pages/team-battle/components/AppBackground.vue @@ -0,0 +1,91 @@ + + + + + diff --git a/src/pages/team-battle/components/Avatar.vue b/src/pages/team-battle/components/Avatar.vue new file mode 100644 index 0000000..c5ba5bb --- /dev/null +++ b/src/pages/team-battle/components/Avatar.vue @@ -0,0 +1,123 @@ + + + + + diff --git a/src/pages/team-battle/components/BackToGame.vue b/src/pages/team-battle/components/BackToGame.vue new file mode 100644 index 0000000..748db2e --- /dev/null +++ b/src/pages/team-battle/components/BackToGame.vue @@ -0,0 +1,138 @@ + + + + + diff --git a/src/pages/team-battle/components/BattleFooter.vue b/src/pages/team-battle/components/BattleFooter.vue new file mode 100644 index 0000000..c7c2442 --- /dev/null +++ b/src/pages/team-battle/components/BattleFooter.vue @@ -0,0 +1,203 @@ += + + + + + diff --git a/src/pages/team-battle/components/BattleHeader.vue b/src/pages/team-battle/components/BattleHeader.vue new file mode 100644 index 0000000..633d086 --- /dev/null +++ b/src/pages/team-battle/components/BattleHeader.vue @@ -0,0 +1,200 @@ + + + + + diff --git a/src/pages/team-battle/components/BowPower.vue b/src/pages/team-battle/components/BowPower.vue new file mode 100644 index 0000000..9153a2b --- /dev/null +++ b/src/pages/team-battle/components/BowPower.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/src/pages/team-battle/components/BowTarget.vue b/src/pages/team-battle/components/BowTarget.vue new file mode 100644 index 0000000..18f82cc --- /dev/null +++ b/src/pages/team-battle/components/BowTarget.vue @@ -0,0 +1,451 @@ + + + + + diff --git a/src/pages/team-battle/components/Container.vue b/src/pages/team-battle/components/Container.vue new file mode 100644 index 0000000..5e3ce8e --- /dev/null +++ b/src/pages/team-battle/components/Container.vue @@ -0,0 +1,353 @@ + + + + + diff --git a/src/pages/team-battle/components/Guide.vue b/src/pages/team-battle/components/Guide.vue new file mode 100644 index 0000000..0400dd6 --- /dev/null +++ b/src/pages/team-battle/components/Guide.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/src/pages/team-battle/components/Header.vue b/src/pages/team-battle/components/Header.vue new file mode 100644 index 0000000..24a51e3 --- /dev/null +++ b/src/pages/team-battle/components/Header.vue @@ -0,0 +1,328 @@ + + + + + diff --git a/src/pages/team-battle/components/HeaderProgress.vue b/src/pages/team-battle/components/HeaderProgress.vue new file mode 100644 index 0000000..ce1db3e --- /dev/null +++ b/src/pages/team-battle/components/HeaderProgress.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/src/pages/team-battle/components/IconButton.vue b/src/pages/team-battle/components/IconButton.vue new file mode 100644 index 0000000..bc466dd --- /dev/null +++ b/src/pages/team-battle/components/IconButton.vue @@ -0,0 +1,39 @@ + + + + diff --git a/src/pages/team-battle/components/PointSwitcher.vue b/src/pages/team-battle/components/PointSwitcher.vue new file mode 100644 index 0000000..1edf96e --- /dev/null +++ b/src/pages/team-battle/components/PointSwitcher.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/pages/team-battle/components/RoundEndTip.vue b/src/pages/team-battle/components/RoundEndTip.vue new file mode 100644 index 0000000..cc9a6f2 --- /dev/null +++ b/src/pages/team-battle/components/RoundEndTip.vue @@ -0,0 +1,172 @@ + + + + + diff --git a/src/pages/team-battle/components/SButton.vue b/src/pages/team-battle/components/SButton.vue new file mode 100644 index 0000000..a4d1bcf --- /dev/null +++ b/src/pages/team-battle/components/SButton.vue @@ -0,0 +1,96 @@ + + + + + diff --git a/src/pages/team-battle/components/SModal.vue b/src/pages/team-battle/components/SModal.vue new file mode 100644 index 0000000..3a0ba89 --- /dev/null +++ b/src/pages/team-battle/components/SModal.vue @@ -0,0 +1,108 @@ + + + + + diff --git a/src/pages/team-battle/components/ScreenHint.vue b/src/pages/team-battle/components/ScreenHint.vue new file mode 100644 index 0000000..e3fb03d --- /dev/null +++ b/src/pages/team-battle/components/ScreenHint.vue @@ -0,0 +1,89 @@ + + + + + diff --git a/src/pages/team-battle/components/ShootProgress2.vue b/src/pages/team-battle/components/ShootProgress2.vue new file mode 100644 index 0000000..89af288 --- /dev/null +++ b/src/pages/team-battle/components/ShootProgress2.vue @@ -0,0 +1,215 @@ + + + + + diff --git a/src/pages/team-battle/components/TeamAvatars.vue b/src/pages/team-battle/components/TeamAvatars.vue new file mode 100644 index 0000000..3eb7a3b --- /dev/null +++ b/src/pages/team-battle/components/TeamAvatars.vue @@ -0,0 +1,150 @@ + + + + + diff --git a/src/pages/team-battle/components/TestDistance.vue b/src/pages/team-battle/components/TestDistance.vue new file mode 100644 index 0000000..16a27e0 --- /dev/null +++ b/src/pages/team-battle/components/TestDistance.vue @@ -0,0 +1,193 @@ + + + + + diff --git a/src/pages/team-battle/index.vue b/src/pages/team-battle/index.vue new file mode 100644 index 0000000..b269f64 --- /dev/null +++ b/src/pages/team-battle/index.vue @@ -0,0 +1,1277 @@ + + + + + From c5a8100c380cced80c765202bca08ebe7498ba4f Mon Sep 17 00:00:00 2001 From: zhangyibo95 <690096405@qq.com> Date: Tue, 26 May 2026 17:58:54 +0800 Subject: [PATCH 2/2] =?UTF-8?q?update:=E4=BF=AE=E5=A4=8D=E9=9D=B6=E7=BA=B8?= =?UTF-8?q?=E8=B4=B4=E8=BE=B9=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/BowTarget.vue | 141 +++++++++++++----- .../team-battle/components/BowTarget.vue | 141 +++++++++++++----- 2 files changed, 208 insertions(+), 74 deletions(-) diff --git a/src/components/BowTarget.vue b/src/components/BowTarget.vue index b1e6c5c..79ee41d 100644 --- a/src/components/BowTarget.vue +++ b/src/components/BowTarget.vue @@ -34,6 +34,18 @@ const props = defineProps({ type: Boolean, default: false, }, + targetRadius: { + type: Number, + default: 20, + }, + hitRadiusPx: { + type: Number, + default: 2, + }, + zoomHitRadiusPx: { + type: Number, + default: 5, + }, }); const pMode = ref(true); @@ -80,13 +92,79 @@ watch( } ); -function calcRealX(num, offset = 3.4) { - const len = 20.4 + num; - return `calc(${(len / 40.8) * 100 - offset / 2}%)`; +const safeTargetRadius = computed(() => { + const radius = Number(props.targetRadius); + return Number.isFinite(radius) && radius > 0 ? radius : 20; +}); + +const currentHitRadiusPx = computed(() => { + const radius = Number( + pMode.value ? props.zoomHitRadiusPx : props.hitRadiusPx + ); + return Number.isFinite(radius) && radius >= 0 ? radius : 0; +}); + +function getShotPoint(shot, fallbackCenter = false) { + const x = Number(shot?.x); + const y = Number(shot?.y); + if (Number.isFinite(x) && Number.isFinite(y)) return { x, y }; + return fallbackCenter ? { x: 0, y: 0 } : null; } -function calcRealY(num, offset = 3.4) { - const len = num < 0 ? Math.abs(num) + 20.4 : 20.4 - num; - return `calc(${(len / 40.8) * 100 - offset / 2}%)`; + +function getPointDirection(point) { + if (!point) return null; + const distance = Math.sqrt(point.x * point.x + point.y * point.y); + if (distance === 0) return null; + + return { + x: point.x / distance, + y: point.y / distance, + }; +} + +function formatPxOffset(value) { + if (!value) return ""; + const operator = value > 0 ? "+" : "-"; + return ` ${operator} ${Math.abs(value)}px`; +} + +function formatTargetPosition(percent, offset) { + const pxOffset = formatPxOffset(offset); + return pxOffset ? `calc(${percent}%${pxOffset})` : `${percent}%`; +} + +function getTargetPositionStyle(point, offsetPx = 0) { + if (!point) return { display: "none" }; + + const radius = safeTargetRadius.value; + const diameter = radius * 2; + const direction = getPointDirection(point); + const xOffset = direction ? direction.x * offsetPx : 0; + const yOffset = direction ? -direction.y * offsetPx : 0; + const leftPercent = ((point.x + radius) / diameter) * 100; + const topPercent = ((radius - point.y) / diameter) * 100; + + return { + left: formatTargetPosition(leftPercent, xOffset), + top: formatTargetPosition(topPercent, yOffset), + transform: "translate(-50%, -50%)", + }; +} + +function getHitStyle(shot) { + const radius = currentHitRadiusPx.value; + const point = getShotPoint(shot); + + return { + ...getTargetPositionStyle(point, radius), + width: `${radius * 2}px`, + height: `${radius * 2}px`, + }; +} + +function getTipStyle(shot) { + const point = getShotPoint(shot, true); + return getTargetPositionStyle(point, shot?.ring ? currentHitRadiusPx.value : 0); } const simulShoot = async () => { if (device.value.deviceId) await simulShootAPI(device.value.deviceId); @@ -169,20 +247,14 @@ onBeforeUnmount(() => { 经验 +1 {{ latestOne.ringX ? "X" : latestOne.ring || "未上靶" }} @@ -193,20 +265,14 @@ onBeforeUnmount(() => { user.id === bluelatestOne.playerId " class="e-value fade-in-out" - :style="{ - left: calcRealX(bluelatestOne.ring ? bluelatestOne.x : 0, 20), - top: calcRealY(bluelatestOne.ring ? bluelatestOne.y : 0, 40), - }" + :style="getTipStyle(bluelatestOne)" > 经验 +1 {{ bluelatestOne.ringX ? "X" : bluelatestOne.ring || "未上靶" }} @@ -217,8 +283,7 @@ onBeforeUnmount(() => { index === scores.length - 1 && latestOne ? 'pump-in' : '' }`" :style="{ - left: calcRealX(bow.x, pMode ? '3.4' : '2'), - top: calcRealY(bow.y, pMode ? '3.4' : '2'), + ...getHitStyle(bow), backgroundColor: mode === 'solo' ? '#00bf04' : '#FF0000', }" >{{ index + 1 }} { index === blueScores.length - 1 && bluelatestOne ? 'pump-in' : '' }`" :style="{ - left: calcRealX(bow.x, pMode ? '3.4' : '2'), - top: calcRealY(bow.y, pMode ? '3.4' : '2'), + ...getHitStyle(bow), backgroundColor: '#1840FF', }" > @@ -302,21 +366,11 @@ onBeforeUnmount(() => { z-index: 1; color: #fff; transition: all 0.3s ease; -} -.s-point { - width: 4px; - height: 4px; - min-width: 4px; - min-height: 4px; + box-sizing: border-box; } .b-point { - width: 10px; - height: 10px; - min-width: 10px; - min-height: 10px; border: 1px solid #fff; z-index: 1; - box-sizing: border-box; display: flex; justify-content: center; align-items: center; @@ -332,6 +386,19 @@ onBeforeUnmount(() => { transform: translate(-50%, -50%);*/ margin-top: 2rpx; } +@keyframes target-pump-in { + from { + transform: translate(-50%, -50%) scale(2); + } + + to { + transform: translate(-50%, -50%) scale(1); + } +} +.hit.pump-in { + animation: target-pump-in 0.3s ease-out forwards; + transform-origin: center center; +} .header { width: 100%; display: flex; diff --git a/src/pages/team-battle/components/BowTarget.vue b/src/pages/team-battle/components/BowTarget.vue index 18f82cc..c855fea 100644 --- a/src/pages/team-battle/components/BowTarget.vue +++ b/src/pages/team-battle/components/BowTarget.vue @@ -38,6 +38,18 @@ const props = defineProps({ type: Boolean, default: false, }, + targetRadius: { + type: Number, + default: 20, + }, + hitRadiusPx: { + type: Number, + default: 2, + }, + zoomHitRadiusPx: { + type: Number, + default: 5, + }, }); const pMode = ref(true); @@ -75,13 +87,79 @@ watch( { immediate: true } ); -function calcRealX(num, offset = 3.4) { - const len = 20.4 + num; - return `calc(${(len / 40.8) * 100 - offset / 2}%)`; +const safeTargetRadius = computed(() => { + const radius = Number(props.targetRadius); + return Number.isFinite(radius) && radius > 0 ? radius : 20; +}); + +const currentHitRadiusPx = computed(() => { + const radius = Number( + pMode.value ? props.zoomHitRadiusPx : props.hitRadiusPx + ); + return Number.isFinite(radius) && radius >= 0 ? radius : 0; +}); + +function getShotPoint(shot, fallbackCenter = false) { + const x = Number(shot?.x); + const y = Number(shot?.y); + if (Number.isFinite(x) && Number.isFinite(y)) return { x, y }; + return fallbackCenter ? { x: 0, y: 0 } : null; } -function calcRealY(num, offset = 3.4) { - const len = num < 0 ? Math.abs(num) + 20.4 : 20.4 - num; - return `calc(${(len / 40.8) * 100 - offset / 2}%)`; + +function getPointDirection(point) { + if (!point) return null; + const distance = Math.sqrt(point.x * point.x + point.y * point.y); + if (distance === 0) return null; + + return { + x: point.x / distance, + y: point.y / distance, + }; +} + +function formatPxOffset(value) { + if (!value) return ""; + const operator = value > 0 ? "+" : "-"; + return ` ${operator} ${Math.abs(value)}px`; +} + +function formatTargetPosition(percent, offset) { + const pxOffset = formatPxOffset(offset); + return pxOffset ? `calc(${percent}%${pxOffset})` : `${percent}%`; +} + +function getTargetPositionStyle(point, offsetPx = 0) { + if (!point) return { display: "none" }; + + const radius = safeTargetRadius.value; + const diameter = radius * 2; + const direction = getPointDirection(point); + const xOffset = direction ? direction.x * offsetPx : 0; + const yOffset = direction ? -direction.y * offsetPx : 0; + const leftPercent = ((point.x + radius) / diameter) * 100; + const topPercent = ((radius - point.y) / diameter) * 100; + + return { + left: formatTargetPosition(leftPercent, xOffset), + top: formatTargetPosition(topPercent, yOffset), + transform: "translate(-50%, -50%)", + }; +} + +function getHitStyle(shot) { + const radius = currentHitRadiusPx.value; + const point = getShotPoint(shot); + + return { + ...getTargetPositionStyle(point, radius), + width: `${radius * 2}px`, + height: `${radius * 2}px`, + }; +} + +function getTipStyle(shot) { + const point = getShotPoint(shot, true); + return getTargetPositionStyle(point, shot?.ring ? currentHitRadiusPx.value : 0); } const simulShoot = async () => { if (device.value.deviceId) await simulShootAPI(device.value.deviceId); @@ -164,20 +242,14 @@ onBeforeUnmount(() => { 经验 +1 {{ latestOne.ringX ? "X" : latestOne.ring || "未上靶" }} @@ -188,20 +260,14 @@ onBeforeUnmount(() => { user.id === bluelatestOne.playerId " class="e-value fade-in-out" - :style="{ - left: calcRealX(bluelatestOne.ring ? bluelatestOne.x : 0, 20), - top: calcRealY(bluelatestOne.ring ? bluelatestOne.y : 0, 40), - }" + :style="getTipStyle(bluelatestOne)" > 经验 +1 {{ bluelatestOne.ringX ? "X" : bluelatestOne.ring || "未上靶" }} @@ -212,8 +278,7 @@ onBeforeUnmount(() => { index === scores.length - 1 && latestOne ? 'pump-in' : '' }`" :style="{ - left: calcRealX(bow.x, pMode ? '3.4' : '2'), - top: calcRealY(bow.y, pMode ? '3.4' : '2'), + ...getHitStyle(bow), backgroundColor: mode === 'solo' ? '#00bf04' : '#FF0000', }" >{{ index + 1 }} { index === blueScores.length - 1 && bluelatestOne ? 'pump-in' : '' }`" :style="{ - left: calcRealX(bow.x, pMode ? '3.4' : '2'), - top: calcRealY(bow.y, pMode ? '3.4' : '2'), + ...getHitStyle(bow), backgroundColor: '#1840FF', }" > @@ -297,21 +361,11 @@ onBeforeUnmount(() => { z-index: 1; color: #fff; transition: all 0.3s ease; -} -.s-point { - width: 4px; - height: 4px; - min-width: 4px; - min-height: 4px; + box-sizing: border-box; } .b-point { - width: 10px; - height: 10px; - min-width: 10px; - min-height: 10px; border: 1px solid #fff; z-index: 1; - box-sizing: border-box; display: flex; justify-content: center; align-items: center; @@ -327,6 +381,19 @@ onBeforeUnmount(() => { transform: translate(-50%, -50%);*/ margin-top: 2rpx; } +@keyframes target-pump-in { + from { + transform: translate(-50%, -50%) scale(2); + } + + to { + transform: translate(-50%, -50%) scale(1); + } +} +.hit.pump-in { + animation: target-pump-in 0.3s ease-out forwards; + transform-origin: center center; +} .header { width: 100%; display: flex;