update:修复大乱斗特效飘移
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
<script setup>
|
||||
import { ref, watch, onMounted, onBeforeUnmount, computed, nextTick } from "vue";
|
||||
import {
|
||||
ref,
|
||||
watch,
|
||||
onMounted,
|
||||
onBeforeUnmount,
|
||||
computed,
|
||||
nextTick,
|
||||
getCurrentInstance,
|
||||
} from "vue";
|
||||
import PointSwitcher from "@/components/PointSwitcher.vue";
|
||||
import BowShotEffect from "@/components/BowShotEffect.vue";
|
||||
|
||||
@@ -56,8 +64,6 @@ const props = defineProps({
|
||||
const pMode = ref(true);
|
||||
const latestOne = ref(null);
|
||||
const bluelatestOne = ref(null);
|
||||
const prevScores = ref([]);
|
||||
const prevBlueScores = ref([]);
|
||||
const timer = ref(null);
|
||||
const dirTimer = ref(null);
|
||||
const angle = ref(null);
|
||||
@@ -66,7 +72,9 @@ const shotEffect = ref(null);
|
||||
const hiddenRedLatestKey = ref("");
|
||||
const hiddenBlueLatestKey = ref("");
|
||||
const targetShaking = ref(false);
|
||||
const targetSize = ref({ width: 0, height: 0 });
|
||||
const shakeTimer = ref(null);
|
||||
const instance = getCurrentInstance();
|
||||
const ROUND_TIP_OFFSET_Y = -32;
|
||||
const EXPERIENCE_TIP_OFFSET_Y = -68;
|
||||
|
||||
@@ -82,8 +90,14 @@ function buildShotEffectKey(team, shot, index) {
|
||||
].join("-");
|
||||
}
|
||||
|
||||
function hasShotPoint(shot) {
|
||||
const x = Number(shot?.x);
|
||||
const y = Number(shot?.y);
|
||||
return Number.isFinite(x) && Number.isFinite(y);
|
||||
}
|
||||
|
||||
function shouldPlayShotEffect(shot) {
|
||||
return props.isSvip && !!shot && Number(shot.ring) > 0;
|
||||
return props.isSvip && !!shot && Number(shot.ring) > 0 && hasShotPoint(shot);
|
||||
}
|
||||
|
||||
function clearTipTimer() {
|
||||
@@ -154,6 +168,29 @@ function shakeTarget() {
|
||||
});
|
||||
}
|
||||
|
||||
function updateTargetSize() {
|
||||
nextTick(() => {
|
||||
const query = instance?.proxy
|
||||
? uni.createSelectorQuery().in(instance.proxy)
|
||||
: uni.createSelectorQuery();
|
||||
|
||||
query
|
||||
.select(".target")
|
||||
.boundingClientRect((rect) => {
|
||||
const width = Number(rect?.width);
|
||||
const height = Number(rect?.height);
|
||||
if (!Number.isFinite(width) || !Number.isFinite(height)) return;
|
||||
if (width <= 0 || height <= 0) return;
|
||||
targetSize.value = { width, height };
|
||||
})
|
||||
.exec();
|
||||
});
|
||||
}
|
||||
|
||||
function handleWindowResize() {
|
||||
updateTargetSize();
|
||||
}
|
||||
|
||||
function shouldHideRedHit(index) {
|
||||
return !!hiddenRedLatestKey.value && index === props.scores.length - 1;
|
||||
}
|
||||
@@ -163,46 +200,44 @@ function shouldHideBlueHit(index) {
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.scores,
|
||||
(newVal) => {
|
||||
if (newVal.length - prevScores.value.length === 1) {
|
||||
const latestShot = newVal[newVal.length - 1];
|
||||
() => props.scores.length,
|
||||
(newLen, oldLen) => {
|
||||
if (newLen === oldLen + 1) {
|
||||
const latestShot = props.scores[newLen - 1];
|
||||
if (shouldPlayShotEffect(latestShot)) {
|
||||
triggerShotEffect("red", latestShot, newVal.length - 1);
|
||||
triggerShotEffect("red", latestShot, newLen - 1);
|
||||
} else {
|
||||
showShotTip("red", latestShot);
|
||||
}
|
||||
} else if (newVal.length <= prevScores.value.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newLen < oldLen) {
|
||||
latestOne.value = null;
|
||||
hiddenRedLatestKey.value = "";
|
||||
if (shotEffect.value?.team === "red") shotEffect.value = null;
|
||||
}
|
||||
prevScores.value = [...newVal];
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.blueScores,
|
||||
(newVal) => {
|
||||
if (newVal.length - prevBlueScores.value.length === 1) {
|
||||
const latestShot = newVal[newVal.length - 1];
|
||||
() => props.blueScores.length,
|
||||
(newLen, oldLen) => {
|
||||
if (newLen === oldLen + 1) {
|
||||
const latestShot = props.blueScores[newLen - 1];
|
||||
if (shouldPlayShotEffect(latestShot)) {
|
||||
triggerShotEffect("blue", latestShot, newVal.length - 1);
|
||||
triggerShotEffect("blue", latestShot, newLen - 1);
|
||||
} else {
|
||||
showShotTip("blue", latestShot);
|
||||
}
|
||||
} else if (newVal.length <= prevBlueScores.value.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newLen < oldLen) {
|
||||
bluelatestOne.value = null;
|
||||
hiddenBlueLatestKey.value = "";
|
||||
if (shotEffect.value?.team === "blue") shotEffect.value = null;
|
||||
}
|
||||
prevBlueScores.value = [...newVal];
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -349,6 +384,8 @@ async function onReceiveMessage(message) {
|
||||
|
||||
onMounted(() => {
|
||||
uni.$on("socket-inbox", onReceiveMessage);
|
||||
updateTargetSize();
|
||||
if (uni.onWindowResize) uni.onWindowResize(handleWindowResize);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
@@ -365,6 +402,7 @@ onBeforeUnmount(() => {
|
||||
shakeTimer.value = null;
|
||||
}
|
||||
uni.$off("socket-inbox", onReceiveMessage);
|
||||
if (uni.offWindowResize) uni.offWindowResize(handleWindowResize);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -461,6 +499,9 @@ onBeforeUnmount(() => {
|
||||
:shot="shotEffect && shotEffect.shot"
|
||||
:playKey="shotEffect ? shotEffect.key : ''"
|
||||
:targetRadius="safeTargetRadius"
|
||||
:targetWidth="targetSize.width"
|
||||
:targetHeight="targetSize.height"
|
||||
:hitOffsetPx="currentHitRadiusPx"
|
||||
@impact="shakeTarget"
|
||||
@complete="completeShotEffect"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user