Files
shoot-miniprograms/src/components/TestDistance.vue
2025-09-15 11:23:22 +08:00

206 lines
4.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import { ref, onMounted, onBeforeUnmount } from "vue";
import Guide from "@/components/Guide.vue";
import BowPower from "@/components/BowPower.vue";
import Avatar from "@/components/Avatar.vue";
import audioManager from "@/audioManager";
import { simulShootAPI } from "@/apis";
import { checkConnection } from "@/util";
import { MESSAGETYPES } from "@/constants";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
const { user, device } = storeToRefs(store);
const props = defineProps({
guide: {
type: Boolean,
default: true,
},
isBattle: {
type: Boolean,
default: false,
},
});
const arrow = ref({});
const power = ref(0);
const distance = ref(0);
const debugInfo = ref("");
const showsimul = ref(false);
const count = ref(15);
const timer = ref(null);
const updateTimer = (value) => {
count.value = Math.round(value);
};
onMounted(() => {
audioManager.play("请射箭测试距离");
timer.value = setInterval(() => {
if (count.value > 0) count.value -= 1;
else clearInterval(timer.value);
}, 1000);
uni.$on("update-timer", updateTimer);
});
onBeforeUnmount(() => {
if (timer.value) clearInterval(timer.value);
uni.$off("update-timer", updateTimer);
});
async function onReceiveMessage(messages = []) {
messages.forEach((msg) => {
if (msg.constructor === MESSAGETYPES.ShootSyncMeArrowID) {
arrow.value = msg.target;
power.value = msg.target.battery;
distance.value = Number((msg.target.dst / 100).toFixed(2));
debugInfo.value = msg.target;
audioManager.play("距离合格");
} else if (msg.constructor === MESSAGETYPES.InvalidShot) {
distance.value = Number((msg.target.dst / 100).toFixed(2));
audioManager.play("距离不足");
}
});
}
const simulShoot = async () => {
if (device.value.deviceId) await simulShootAPI(device.value.deviceId);
};
onMounted(() => {
checkConnection();
uni.$on("socket-inbox", onReceiveMessage);
const accountInfo = uni.getAccountInfoSync();
const envVersion = accountInfo.miniProgram.envVersion;
if (envVersion !== "release") showsimul.value = true;
});
onBeforeUnmount(() => {
uni.$off("socket-inbox", onReceiveMessage);
});
</script>
<template>
<view class="container">
<Guide v-show="guide">
<view
:style="{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
paddingRight: '10px',
}"
>
<view :style="{ display: 'flex', flexDirection: 'column' }">
<text :style="{ color: '#fed847' }">请确保站距达到5米</text>
<text>低于5米的射箭无效</text>
</view>
</view>
</Guide>
<view class="test-area">
<image
class="text-bg"
src="https://static.shelingxingqiu.com/attachment/2025-07-05/db3skuq1n9rj4fmld4.png"
mode="widthFix"
/>
<button
class="simul"
@click="simulShoot"
hover-class="none"
v-if="showsimul"
>
模拟射箭
</button>
<view class="warnning-text">
<block v-if="distance > 0">
<text>当前距离{{ distance }}</text>
<text v-if="distance >= 5">已达到距离要求</text>
<text v-else>请调整站位</text>
</block>
<block v-else>
<text>请射箭测试站距</text>
</block>
</view>
<view class="user-row">
<Avatar :src="user.avatar" :size="35" />
<BowPower :power="power" />
</view>
</view>
<view v-if="isBattle" class="ready-timer">
<image src="../static/test-tip.png" mode="widthFix" />
<view>
<text>具体正式比赛还有</text>
<text>{{ count }}</text>
<text></text>
</view>
</view>
</view>
</template>
<style scoped>
.container {
width: 100vw;
max-height: 70vh;
}
.ready-timer {
display: flex;
flex-direction: column;
align-items: center;
transform: translateY(-10vw);
}
.ready-timer > image:first-child {
width: 40%;
}
.ready-timer > view {
width: 80%;
height: 45px;
background-color: #545454;
border-radius: 30px;
display: flex;
justify-content: center;
align-items: center;
transform: translateY(-8vw);
color: #bebebe;
font-size: 15px;
}
.ready-timer > view > text:nth-child(2) {
color: #fed847;
font-size: 20px;
width: 22px;
text-align: center;
}
.test-area {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
width: 100%;
height: 112vw;
position: relative;
}
.test-area > view:last-child {
padding: 15px;
width: calc(100% - 30px);
}
.text-bg {
width: 100%;
position: absolute;
top: -14.4%;
left: 0;
}
.warnning-text {
color: #fed847;
font-size: 27px;
display: flex;
flex-direction: column;
justify-content: center;
height: 40%;
}
.warnning-text > text {
width: 70vw;
text-align: center;
}
.simul {
position: absolute;
color: #fff;
right: 10px;
}
</style>