练习流程修改

This commit is contained in:
kron
2026-01-07 15:12:30 +08:00
parent 1f75045db4
commit 23cd5bd835
3 changed files with 50 additions and 91 deletions

View File

@@ -38,6 +38,10 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
onStop: {
type: Function,
default: () => {},
},
}); });
const barColor = ref("#fed847"); const barColor = ref("#fed847");
@@ -75,34 +79,25 @@ watch(
} }
); );
watch( const resetTimer = (count) => {
() => props.tips, if (timer.value) clearInterval(timer.value);
(newVal) => { remain.value = Math.round(count);
if (newVal.includes("红队")) barColor.value = "#FF6060"; if (remain.value > 0) {
if (newVal.includes("蓝队")) barColor.value = "#5FADFF"; timer.value = setInterval(() => {
if (newVal.includes("红队") || newVal.includes("蓝队")) { if (remain.value === 0) {
if (timer.value) clearInterval(timer.value); clearInterval(timer.value);
remain.value = props.total; props.onStop();
timer.value = setInterval(() => { }
if (remain.value > 0) remain.value--; if (remain.value > 0) remain.value--;
}, 1000); }, 1000);
}
},
{
immediate: true,
} }
); };
watch( watch(
() => props.start, () => props.start,
(newVal) => { (newVal) => {
if (timer.value) clearInterval(timer.value); if (newVal) resetTimer(props.total);
if (newVal) { else if (timer.value) clearInterval(timer.value);
remain.value = props.total;
timer.value = setInterval(() => {
if (remain.value > 0) remain.value--;
}, 1000);
}
}, },
{ {
immediate: true, immediate: true,
@@ -116,16 +111,6 @@ const tipContent = computed(() => {
return props.start && remain.value === 0 ? "时间到!" : props.tips; return props.start && remain.value === 0 ? "时间到!" : props.tips;
}); });
const updateRemain = (value) => {
if (timer.value) clearInterval(timer.value);
remain.value = Math.round(value);
if (remain.value > 0) {
timer.value = setInterval(() => {
if (remain.value > 0) remain.value--;
}, 1000);
}
};
const updateSound = () => { const updateSound = () => {
sound.value = !sound.value; sound.value = !sound.value;
audioManager.setMuted(!sound.value); audioManager.setMuted(!sound.value);
@@ -194,13 +179,13 @@ const playSound = (key) => {
}; };
onMounted(() => { onMounted(() => {
uni.$on("update-ramain", updateRemain); uni.$on("update-ramain", resetTimer);
uni.$on("socket-inbox", onReceiveMessage); uni.$on("socket-inbox", onReceiveMessage);
uni.$on("play-sound", playSound); uni.$on("play-sound", playSound);
}); });
onBeforeUnmount(() => { onBeforeUnmount(() => {
uni.$off("update-ramain", updateRemain); uni.$off("update-ramain", resetTimer);
uni.$off("socket-inbox", onReceiveMessage); uni.$off("socket-inbox", onReceiveMessage);
uni.$off("play-sound", playSound); uni.$off("play-sound", playSound);
if (timer.value) clearInterval(timer.value); if (timer.value) clearInterval(timer.value);

View File

@@ -12,13 +12,16 @@ import BowPower from "@/components/BowPower.vue";
import TestDistance from "@/components/TestDistance.vue"; import TestDistance from "@/components/TestDistance.vue";
import BubbleTip from "@/components/BubbleTip.vue"; import BubbleTip from "@/components/BubbleTip.vue";
import audioManager from "@/audioManager"; import audioManager from "@/audioManager";
import { createPractiseAPI } from "@/apis";
import { createPractiseAPI, getPractiseAPI } from "@/apis";
import { generateCanvasImage, wxShare, debounce } from "@/util"; import { generateCanvasImage, wxShare, debounce } from "@/util";
import { MESSAGETYPES, roundsName } from "@/constants"; import { MESSAGETYPES, roundsName } from "@/constants";
import useStore from "@/store"; import useStore from "@/store";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
const store = useStore(); const store = useStore();
const { user } = storeToRefs(store); const { user } = storeToRefs(store);
const start = ref(false); const start = ref(false);
const scores = ref([]); const scores = ref([]);
const total = 12; const total = 12;
@@ -27,8 +30,6 @@ const practiseResult = ref({});
const practiseId = ref(""); const practiseId = ref("");
const showGuide = ref(false); const showGuide = ref(false);
const tips = ref(""); const tips = ref("");
const wait = ref(0);
const timer = ref(null);
const onReady = async () => { const onReady = async () => {
const result = await createPractiseAPI(total, 2); const result = await createPractiseAPI(total, 2);
@@ -39,6 +40,11 @@ const onReady = async () => {
audioManager.play("练习开始"); audioManager.play("练习开始");
}; };
const onOver = async () => {
start.value = false;
practiseResult.value = await getPractiseAPI(practiseId.value);
};
async function onReceiveMessage(messages = []) { async function onReceiveMessage(messages = []) {
messages.forEach((msg) => { messages.forEach((msg) => {
if (msg.constructor === MESSAGETYPES.ShootSyncMeArrowID) { if (msg.constructor === MESSAGETYPES.ShootSyncMeArrowID) {
@@ -54,43 +60,8 @@ async function onReceiveMessage(messages = []) {
showGuide.value = false; showGuide.value = false;
}, 3000); }, 3000);
} }
} if (scores.value.length === total) {
} else if (msg.constructor === MESSAGETYPES.ShootSyncMePracticeID) { setTimeout(onOver, 1500);
if (practiseId.value && practiseId.value === msg.practice.id) {
if (timer.value) {
clearInterval(timer.value);
timer.value = null;
}
setTimeout(() => {
start.value = false;
practiseResult.value = {
...msg.practice,
arrows: JSON.parse(msg.practice.arrows),
lvl: msg.lvl,
};
}, 1500);
}
} else if (msg.constructor === MESSAGETYPES.HalfTimeOver) {
wait.value = msg.wait;
if (msg.wait === 20) {
uni.$emit("update-ramain", 0);
for (let i = 0; i < 6; i++) {
if (!scores.value[i]) scores.value[i] = { x: -30, y: -30, ring: 0 };
}
}
if (msg.wait === 0) {
let count = 60;
uni.$emit("update-ramain", count);
audioManager.play("练习开始");
if (!timer.value) {
timer.value = setInterval(() => {
count -= 1;
if (count === 30) {
audioManager.play("最后30秒");
clearInterval(timer.value);
timer.value = null;
}
}, 1000);
} }
} }
} }
@@ -154,7 +125,7 @@ onBeforeUnmount(() => {
}轮` }轮`
}`" }`"
:start="start" :start="start"
:total="60" :onStop="onOver"
/> />
<view class="user-row"> <view class="user-row">
<Avatar :src="user.avatar" :size="35" /> <Avatar :src="user.avatar" :size="35" />
@@ -168,7 +139,6 @@ onBeforeUnmount(() => {
:totalRound="start ? total / 4 : 0" :totalRound="start ? total / 4 : 0"
:currentRound="currentRound" :currentRound="currentRound"
:scores="scores" :scores="scores"
:stop="wait > 0"
/> />
<ScorePanel2 :scores="scores.map((s) => s.ring)" /> <ScorePanel2 :scores="scores.map((s) => s.ring)" />
<ScoreResult <ScoreResult

View File

@@ -11,13 +11,16 @@ import BowPower from "@/components/BowPower.vue";
import TestDistance from "@/components/TestDistance.vue"; import TestDistance from "@/components/TestDistance.vue";
import BubbleTip from "@/components/BubbleTip.vue"; import BubbleTip from "@/components/BubbleTip.vue";
import audioManager from "@/audioManager"; import audioManager from "@/audioManager";
import { createPractiseAPI } from "@/apis";
import { createPractiseAPI, getPractiseAPI } from "@/apis";
import { generateCanvasImage, wxShare, debounce } from "@/util"; import { generateCanvasImage, wxShare, debounce } from "@/util";
import { MESSAGETYPES } from "@/constants"; import { MESSAGETYPES } from "@/constants";
import useStore from "@/store"; import useStore from "@/store";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
const store = useStore(); const store = useStore();
const { user } = storeToRefs(store); const { user } = storeToRefs(store);
const start = ref(false); const start = ref(false);
const scores = ref([]); const scores = ref([]);
const total = 36; const total = 36;
@@ -35,6 +38,11 @@ const onReady = async () => {
}, 300); }, 300);
}; };
const onOver = async () => {
start.value = false;
practiseResult.value = await getPractiseAPI(practiseId.value);
};
async function onReceiveMessage(messages = []) { async function onReceiveMessage(messages = []) {
messages.forEach((msg) => { messages.forEach((msg) => {
if (msg.constructor === MESSAGETYPES.ShootSyncMeArrowID) { if (msg.constructor === MESSAGETYPES.ShootSyncMeArrowID) {
@@ -46,18 +54,9 @@ async function onReceiveMessage(messages = []) {
showGuide.value = false; showGuide.value = false;
}, 3000); }, 3000);
} }
} if (scores.value.length === total) {
} setTimeout(onOver, 1500);
if (msg.constructor === MESSAGETYPES.ShootSyncMePracticeID) { }
if (practiseId.value && practiseId.value === msg.practice.id) {
setTimeout(() => {
start.value = false;
practiseResult.value = {
...msg.practice,
arrows: JSON.parse(msg.practice.arrows),
lvl: msg.lvl,
};
}, 1500);
} }
} }
}); });
@@ -106,7 +105,12 @@ onBeforeUnmount(() => {
<view> <view>
<TestDistance v-if="!practiseId" /> <TestDistance v-if="!practiseId" />
<block v-if="practiseId"> <block v-if="practiseId">
<ShootProgress :start="start" :tips="`请连续射${total}支箭`" /> <ShootProgress
:tips="`请连续射${total}支箭`"
:start="start"
:total="360"
:onStop="onOver"
/>
<view class="user-row"> <view class="user-row">
<Avatar :src="user.avatar" :size="35" /> <Avatar :src="user.avatar" :size="35" />
<BubbleTip v-if="showGuide" type="normal2"> <BubbleTip v-if="showGuide" type="normal2">