2025-05-10 16:57:36 +08:00
|
|
|
|
<script setup>
|
2025-06-08 12:52:49 +08:00
|
|
|
|
import { ref, watch } from "vue";
|
2025-05-16 15:56:54 +08:00
|
|
|
|
import BowPower from "@/components/BowPower.vue";
|
2025-05-29 23:45:44 +08:00
|
|
|
|
const props = defineProps({
|
2025-05-10 16:57:36 +08:00
|
|
|
|
totalRound: {
|
|
|
|
|
|
type: Number,
|
|
|
|
|
|
default: 0,
|
|
|
|
|
|
},
|
|
|
|
|
|
currentRound: {
|
|
|
|
|
|
type: Number,
|
|
|
|
|
|
default: 0,
|
|
|
|
|
|
},
|
|
|
|
|
|
avatar: {
|
|
|
|
|
|
type: String,
|
|
|
|
|
|
default: "",
|
|
|
|
|
|
},
|
|
|
|
|
|
power: {
|
|
|
|
|
|
type: Number,
|
|
|
|
|
|
default: 0,
|
|
|
|
|
|
},
|
|
|
|
|
|
tips: {
|
|
|
|
|
|
type: String,
|
|
|
|
|
|
default: "",
|
|
|
|
|
|
},
|
|
|
|
|
|
debug: {
|
|
|
|
|
|
type: Boolean,
|
|
|
|
|
|
default: false,
|
|
|
|
|
|
},
|
2025-05-29 23:45:44 +08:00
|
|
|
|
scores: {
|
|
|
|
|
|
type: Array,
|
|
|
|
|
|
default: () => [],
|
|
|
|
|
|
},
|
2025-06-14 22:45:07 +08:00
|
|
|
|
blueScores: {
|
|
|
|
|
|
type: Array,
|
|
|
|
|
|
default: () => [],
|
|
|
|
|
|
},
|
2025-06-17 16:02:29 +08:00
|
|
|
|
showLatestArrow: {
|
2025-06-08 20:59:41 +08:00
|
|
|
|
type: Boolean,
|
|
|
|
|
|
default: true,
|
|
|
|
|
|
},
|
2025-06-17 19:35:21 +08:00
|
|
|
|
showE: {
|
|
|
|
|
|
type: Boolean,
|
|
|
|
|
|
default: true,
|
|
|
|
|
|
},
|
2025-05-10 16:57:36 +08:00
|
|
|
|
});
|
2025-05-29 23:45:44 +08:00
|
|
|
|
|
2025-06-08 12:52:49 +08:00
|
|
|
|
const showRoundTips = ref(false);
|
2025-06-15 15:53:57 +08:00
|
|
|
|
const prevLength = ref(0);
|
2025-06-15 20:55:34 +08:00
|
|
|
|
const timer = ref(null);
|
2025-06-08 12:52:49 +08:00
|
|
|
|
|
|
|
|
|
|
watch(
|
|
|
|
|
|
() => props.scores,
|
|
|
|
|
|
(newVal) => {
|
2025-06-15 15:53:57 +08:00
|
|
|
|
if (newVal.length - prevLength.value === 1) {
|
2025-06-15 20:55:34 +08:00
|
|
|
|
if (timer.value) clearTimeout(timer.value);
|
2025-06-08 12:52:49 +08:00
|
|
|
|
showRoundTips.value = true;
|
2025-06-15 20:55:34 +08:00
|
|
|
|
timer.value = setTimeout(() => {
|
2025-06-08 12:52:49 +08:00
|
|
|
|
showRoundTips.value = false;
|
2025-06-15 15:53:57 +08:00
|
|
|
|
}, 1000);
|
2025-06-08 12:52:49 +08:00
|
|
|
|
}
|
2025-06-15 15:53:57 +08:00
|
|
|
|
prevLength.value = newVal.length;
|
2025-06-08 12:52:49 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
deep: true,
|
|
|
|
|
|
}
|
|
|
|
|
|
);
|
|
|
|
|
|
|
2025-05-29 23:45:44 +08:00
|
|
|
|
function calcRealX(num) {
|
|
|
|
|
|
const len = 20 + num;
|
|
|
|
|
|
return `calc(${(len / 40) * 100}% - 10px)`;
|
|
|
|
|
|
}
|
|
|
|
|
|
function calcRealY(num) {
|
|
|
|
|
|
const len = num < 0 ? Math.abs(num) + 20 : 20 - num;
|
|
|
|
|
|
return `calc(${(len / 40) * 100}% - 10px)`;
|
|
|
|
|
|
}
|
2025-05-10 16:57:36 +08:00
|
|
|
|
</script>
|
2025-05-08 22:05:53 +08:00
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<view class="container">
|
|
|
|
|
|
<view class="header">
|
2025-05-30 13:58:43 +08:00
|
|
|
|
<text v-if="debug" class="header-tips">大人,请射箭</text>
|
2025-05-16 15:56:54 +08:00
|
|
|
|
<text v-if="totalRound > 0" class="round-count">{{
|
2025-05-31 14:57:25 +08:00
|
|
|
|
(currentRound > totalRound ? totalRound : currentRound) +
|
|
|
|
|
|
"/" +
|
|
|
|
|
|
totalRound
|
2025-05-10 16:57:36 +08:00
|
|
|
|
}}</text>
|
2025-06-15 20:55:34 +08:00
|
|
|
|
<BowPower :power="power" />
|
2025-05-08 22:05:53 +08:00
|
|
|
|
</view>
|
2025-05-29 23:45:44 +08:00
|
|
|
|
<view class="target">
|
2025-06-08 20:59:41 +08:00
|
|
|
|
<view
|
2025-06-17 19:35:21 +08:00
|
|
|
|
v-if="scores.length && showRoundTips && showLatestArrow && showE"
|
2025-06-08 20:59:41 +08:00
|
|
|
|
class="e-value fade-in"
|
2025-06-08 12:52:49 +08:00
|
|
|
|
>经验 +1</view
|
|
|
|
|
|
>
|
2025-06-17 16:02:29 +08:00
|
|
|
|
<view
|
|
|
|
|
|
v-if="scores.length && showRoundTips && showLatestArrow"
|
|
|
|
|
|
class="round-tip fade-in"
|
2025-06-08 12:52:49 +08:00
|
|
|
|
>{{ scores[scores.length - 1].ring }}<text>环</text></view
|
|
|
|
|
|
>
|
2025-06-17 19:35:21 +08:00
|
|
|
|
<block v-for="(bow, index) in scores" :key="index">
|
|
|
|
|
|
<image
|
|
|
|
|
|
v-if="bow.ring > 0"
|
|
|
|
|
|
:src="
|
|
|
|
|
|
index === scores.length - 1 && !blueScores.length && showLatestArrow
|
|
|
|
|
|
? '../static/hit-icon-green.png'
|
|
|
|
|
|
: '../static/hit-icon.png'
|
|
|
|
|
|
"
|
|
|
|
|
|
:class="`hit ${
|
|
|
|
|
|
index + 1 === scores.length && !blueScores.length && showLatestArrow
|
|
|
|
|
|
? 'pump-in'
|
|
|
|
|
|
: ''
|
|
|
|
|
|
}`"
|
|
|
|
|
|
:style="{
|
|
|
|
|
|
left: calcRealX(bow.x),
|
|
|
|
|
|
top: calcRealY(bow.y),
|
|
|
|
|
|
}"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</block>
|
|
|
|
|
|
<block v-for="(bow, index) in blueScores" :key="index">
|
|
|
|
|
|
<image
|
|
|
|
|
|
v-if="bow.ring > 0"
|
|
|
|
|
|
src="../static/hit-icon-blue.png"
|
|
|
|
|
|
class="hit"
|
|
|
|
|
|
:style="{
|
|
|
|
|
|
left: calcRealX(bow.x),
|
|
|
|
|
|
top: calcRealY(bow.y),
|
|
|
|
|
|
}"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</block>
|
|
|
|
|
|
|
2025-05-29 23:45:44 +08:00
|
|
|
|
<image src="../static/bow-target.png" mode="widthFix" />
|
|
|
|
|
|
</view>
|
2025-05-16 15:56:54 +08:00
|
|
|
|
<view v-if="avatar" class="footer">
|
2025-05-10 16:57:36 +08:00
|
|
|
|
<image :src="avatar" mode="widthFix" />
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<text v-if="tips">{{ tips }}</text>
|
2025-05-08 22:05:53 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.container {
|
|
|
|
|
|
width: calc(100% - 30px);
|
2025-06-05 22:21:40 +08:00
|
|
|
|
padding: 15px;
|
2025-06-17 16:58:24 +08:00
|
|
|
|
/* overflow: hidden; */
|
2025-05-08 22:05:53 +08:00
|
|
|
|
}
|
2025-05-29 23:45:44 +08:00
|
|
|
|
.target {
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
}
|
2025-06-08 12:52:49 +08:00
|
|
|
|
.e-value {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
top: 30%;
|
|
|
|
|
|
left: 60%;
|
|
|
|
|
|
background-color: #0006;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
padding: 4px 7px;
|
|
|
|
|
|
border-radius: 5px;
|
2025-06-13 16:36:18 +08:00
|
|
|
|
z-index: 2;
|
2025-06-08 12:52:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
.round-tip {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
top: 38%;
|
|
|
|
|
|
left: 60%;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
font-size: 30px;
|
|
|
|
|
|
font-weight: bold;
|
2025-06-13 16:36:18 +08:00
|
|
|
|
z-index: 2;
|
2025-06-08 12:52:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
.round-tip > text {
|
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
|
margin-left: 5px;
|
|
|
|
|
|
}
|
2025-05-29 23:45:44 +08:00
|
|
|
|
.target > image:last-child {
|
2025-05-08 22:05:53 +08:00
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
2025-05-29 23:45:44 +08:00
|
|
|
|
.hit {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
width: 20px;
|
|
|
|
|
|
height: 20px;
|
2025-06-13 16:36:18 +08:00
|
|
|
|
z-index: 1;
|
2025-05-29 23:45:44 +08:00
|
|
|
|
}
|
2025-05-08 22:05:53 +08:00
|
|
|
|
.header {
|
2025-05-10 22:16:59 +08:00
|
|
|
|
width: 100%;
|
2025-05-08 22:05:53 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
}
|
2025-05-10 16:57:36 +08:00
|
|
|
|
.header > image:first-child {
|
2025-05-08 22:05:53 +08:00
|
|
|
|
width: 40px;
|
|
|
|
|
|
height: 40px;
|
|
|
|
|
|
}
|
2025-05-16 15:56:54 +08:00
|
|
|
|
.round-count {
|
2025-05-10 16:57:36 +08:00
|
|
|
|
font-size: 20px;
|
|
|
|
|
|
color: #fed847;
|
|
|
|
|
|
top: 75px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.header-tips {
|
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
|
color: #fed847;
|
|
|
|
|
|
}
|
|
|
|
|
|
.footer {
|
|
|
|
|
|
width: calc(100% - 20px);
|
|
|
|
|
|
padding: 0 10px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
margin-top: -40px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.footer > image {
|
|
|
|
|
|
width: 40px;
|
|
|
|
|
|
height: 40px;
|
2025-05-30 13:58:43 +08:00
|
|
|
|
border-radius: 50%;
|
2025-05-10 16:57:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
.container > text {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
color: #fed847;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
line-height: 40px;
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
margin-top: 20px;
|
|
|
|
|
|
}
|
2025-05-08 22:05:53 +08:00
|
|
|
|
</style>
|