Files
shoot-miniprograms/src/components/TestDistance.vue

200 lines
4.6 KiB
Vue
Raw Normal View History

2025-07-05 14:52:41 +08:00
<script setup>
2025-08-25 13:47:32 +08:00
import { ref, onMounted, onBeforeUnmount } from "vue";
2025-07-05 14:52:41 +08:00
import Guide from "@/components/Guide.vue";
import BowPower from "@/components/BowPower.vue";
import Avatar from "@/components/Avatar.vue";
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,
},
2025-08-22 11:51:52 +08:00
isBattle: {
type: Boolean,
default: false,
},
2025-07-05 14:52:41 +08:00
});
const arrow = ref({});
const power = ref(0);
const distance = ref(0);
const debugInfo = ref("");
2025-08-09 12:02:36 +08:00
const showsimul = ref(false);
2025-08-22 11:51:52 +08:00
const count = ref(15);
const timer = ref(null);
const updateTimer = (value) => {
count.value = Math.round(value);
};
onMounted(() => {
timer.value = setInterval(() => {
if (count.value > 0) count.value -= 1;
else clearInterval(timer.value);
}, 1000);
uni.$on("update-timer", updateTimer);
});
2025-08-25 13:47:32 +08:00
onBeforeUnmount(() => {
2025-08-22 11:51:52 +08:00
if (timer.value) clearInterval(timer.value);
uni.$off("update-timer", updateTimer);
});
2025-07-05 14:52:41 +08:00
async function onReceiveMessage(messages = []) {
messages.forEach((msg) => {
if (msg.constructor === MESSAGETYPES.ShootSyncMeArrowID) {
arrow.value = msg.target;
power.value = msg.target.battery;
2025-08-21 13:55:32 +08:00
distance.value = Number((msg.target.dst / 100).toFixed(2));
2025-07-05 14:52:41 +08:00
debugInfo.value = msg.target;
}
});
}
const simulShoot = async () => {
if (device.value.deviceId) await simulShootAPI(device.value.deviceId);
};
onMounted(() => {
checkConnection();
uni.$on("socket-inbox", onReceiveMessage);
2025-08-09 12:02:36 +08:00
const accountInfo = uni.getAccountInfoSync();
const envVersion = accountInfo.miniProgram.envVersion;
if (envVersion !== "release") showsimul.value = true;
2025-07-05 14:52:41 +08:00
});
2025-08-25 13:47:32 +08:00
onBeforeUnmount(() => {
2025-07-05 14:52:41 +08:00
uni.$off("socket-inbox", onReceiveMessage);
});
</script>
<template>
<view class="container">
2025-08-22 11:51:52 +08:00
<Guide v-show="guide">
2025-07-05 14:52:41 +08:00
<view
:style="{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
paddingRight: '10px',
}"
>
<view :style="{ display: 'flex', flexDirection: 'column' }">
2025-08-21 09:36:00 +08:00
<text :style="{ color: '#fed847' }">请确保站距达到5米</text>
<text>低于5米的射箭无效</text>
2025-07-05 14:52:41 +08:00
</view>
</view>
</Guide>
2025-08-22 11:51:52 +08:00
<view class="test-area">
<image
class="text-bg"
src="https://static.shelingxingqiu.com/attachment/2025-07-05/db3skuq1n9rj4fmld4.png"
mode="widthFix"
/>
<button
2025-08-09 12:02:36 +08:00
class="simul"
@click="simulShoot"
2025-08-22 11:51:52 +08:00
hover-class="none"
2025-08-09 12:02:36 +08:00
v-if="showsimul"
>
2025-07-05 14:52:41 +08:00
模拟射箭
2025-08-22 11:51:52 +08:00
</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>
2025-07-05 14:52:41 +08:00
</view>
</view>
</view>
</template>
<style scoped>
.container {
width: 100vw;
2025-08-22 11:51:52 +08:00
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 {
2025-07-05 14:52:41 +08:00
display: flex;
flex-direction: column;
2025-08-22 11:51:52 +08:00
align-items: center;
justify-content: space-between;
width: 100%;
height: 112vw;
position: relative;
}
.test-area > view:last-child {
padding: 15px;
width: calc(100% - 30px);
2025-07-05 14:52:41 +08:00
}
.text-bg {
width: 100%;
2025-08-22 11:51:52 +08:00
position: absolute;
top: -14.4%;
left: 0;
2025-07-05 14:52:41 +08:00
}
.warnning-text {
color: #fed847;
2025-08-22 11:51:52 +08:00
font-size: 27px;
2025-07-05 14:52:41 +08:00
display: flex;
flex-direction: column;
2025-08-22 11:51:52 +08:00
justify-content: center;
height: 40%;
2025-07-05 14:52:41 +08:00
}
.warnning-text > text {
2025-08-21 13:55:32 +08:00
width: 70vw;
2025-07-05 14:52:41 +08:00
text-align: center;
}
2025-08-22 11:51:52 +08:00
.simul {
position: absolute;
2025-07-05 14:52:41 +08:00
color: #fff;
2025-08-22 11:51:52 +08:00
right: 10px;
2025-07-05 14:52:41 +08:00
}
</style>