update:代码备份

This commit is contained in:
2026-05-18 09:20:07 +08:00
parent fc7149121b
commit 21d8d0fbdb
14 changed files with 1350 additions and 10 deletions
@@ -0,0 +1,379 @@
<script setup>
import { ref, watch, onMounted, onBeforeUnmount, computed } from "vue";
import audioManager from "@/audioManager";
import { MESSAGETYPESV2 } from "@/constants";
import { getDirectionText } from "@/util";
import Avatar from "@/components/Avatar.vue";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
const { user } = storeToRefs(store);
const props = defineProps({
show: {
type: Boolean,
default: true,
},
start: {
type: Boolean,
default: false,
},
tips: {
type: String,
default: "",
},
total: {
type: Number,
default: 120,
},
currentRound: {
type: Number,
default: 0,
},
battleId: {
type: String,
default: "",
},
melee: {
type: Boolean,
default: false,
},
onStop: {
type: Function,
default: () => {},
},
});
const barColor = ref("#fed847");
const remain = ref(props.total);
const timer = ref(null);
const sound = ref(true);
const currentRound = ref(props.currentRound);
const currentRoundEnded = ref(false);
const halfTime = ref(false);
const wait = ref(0);
const transitionStyle = ref("all 1s linear");
const progressPercent = computed(() => {
if (!props.total) return 0;
return Math.max(0, Math.min(100, (remain.value / props.total) * 100));
});
const displayName = computed(() => {
return (
user.value?.nickName ||
user.value?.nickname ||
user.value?.name ||
"Archer"
);
});
const avatarSrc = computed(() => {
return user.value?.avatar || "/static/shooter2.png";
});
watch(
() => props.tips,
(newVal) => {
let key = "";
if (newVal.includes("红队")) key = "请红方射箭";
if (newVal.includes("蓝队")) key = "请蓝方射箭";
if (key) {
if (currentRoundEnded.value) {
currentRound.value += 1;
currentRoundEnded.value = false;
if (currentRound.value === 1) audioManager.play("第一轮");
if (currentRound.value === 2) audioManager.play("第二轮");
if (currentRound.value === 3) audioManager.play("第三轮");
if (currentRound.value === 4) audioManager.play("第四轮");
if (currentRound.value === 5) audioManager.play("第五轮");
setTimeout(() => {
audioManager.play(key);
}, 1000);
} else {
audioManager.play(key);
}
}
}
);
const resetTimer = (count) => {
if (timer.value) clearInterval(timer.value);
const newVal = Math.round(count);
if (newVal >= remain.value) {
transitionStyle.value = "none";
remain.value = newVal;
setTimeout(() => {
transitionStyle.value = "all 1s linear";
}, 50);
} else {
remain.value = newVal;
}
if (remain.value > 0) {
timer.value = setInterval(() => {
if (remain.value === 0) {
clearInterval(timer.value);
props.onStop();
}
if (remain.value > 0) remain.value--;
}, 1000);
}
};
watch(
() => props.start,
(newVal) => {
if (newVal) {
resetTimer(props.total);
} else {
remain.value = 0;
clearInterval(timer.value);
}
},
{
immediate: true,
}
);
const tipContent = computed(() => {
if (halfTime.value) {
return props.battleId ? "中场休息" : `中场休息(${wait.value}秒)`;
}
return props.start && remain.value === 0 ? "时间到!" : props.tips;
});
const updateSound = () => {
sound.value = !sound.value;
audioManager.setMuted(!sound.value);
};
async function onReceiveMessage(msg) {
if (Array.isArray(msg)) return;
if (msg.type === MESSAGETYPESV2.BattleStart) {
halfTime.value = false;
audioManager.play("比赛开始");
} else if (msg.type === MESSAGETYPESV2.BattleEnd) {
audioManager.play("比赛结束", false);
} else if (msg.type === MESSAGETYPESV2.ShootResult) {
let arrow = {};
if (msg.details && Array.isArray(msg.details)) {
arrow = msg.details[msg.details.length - 1];
} else {
if (msg.shootData.playerId !== user.value.id) return;
if (msg.shootData) arrow = msg.shootData;
}
let key = [];
key.push(arrow.ring ? `${arrow.ringX ? "X" : arrow.ring}` : "未上靶");
if (arrow.angle !== null) {
key.push(`${getDirectionText(arrow.angle)}调整`);
}
audioManager.play(key, false);
} else if (msg.type === MESSAGETYPESV2.HalfRest) {
halfTime.value = true;
audioManager.play("中场休息");
} else if (msg.type === MESSAGETYPESV2.InvalidShot) {
uni.showToast({
title: "距离不足,无效",
icon: "none",
});
audioManager.play("射击无效");
}
}
const playSound = (key) => {
audioManager.play(key);
};
onMounted(() => {
uni.$on("update-remain", resetTimer);
uni.$on("socket-inbox", onReceiveMessage);
uni.$on("play-sound", playSound);
});
onBeforeUnmount(() => {
uni.$off("update-remain", resetTimer);
uni.$off("socket-inbox", onReceiveMessage);
uni.$off("play-sound", playSound);
if (timer.value) clearInterval(timer.value);
});
</script>
<template>
<view v-if="show" class="progress-card">
<view class="progress-card__header">
<view class="progress-card__profile">
<view class="progress-card__avatar-shell">
<Avatar :src="user.avatar" :size="40" />
</view>
<text class="progress-card__name">{{ displayName }}</text>
</view>
<!-- <button class="progress-card__sound" hover-class="none" @click="updateSound">
<image
class="progress-card__sound-icon"
:src="`/static/sound${sound ? '' : '-off'}-yellow.png`"
mode="aspectFit"
/>
</button> -->
</view>
<view class="progress-card__track-wrap">
<image
class="progress-card__titile"
src="../../../static/training-difficulty-design/text-icon-cgxl.png"
mode="aspectFit"
/>
<view class="progress-card__track">
<view
class="progress-card__fill"
:style="{
width: `${progressPercent}%`,
backgroundColor: barColor,
right: tips.includes('红队') ? 0 : 'unset',
transition: transitionStyle,
}"
/>
<view class="progress-card__badge">
<text class="progress-card__badge-text">剩余{{ remain }}</text>
</view>
</view>
<!-- <text v-if="tipContent" class="progress-card__tip">{{ tipContent }}123</text> -->
</view>
</view>
</template>
<style scoped>
.progress-card {
box-sizing: border-box;
/* padding: 50rpx 30rpx 0 30rpx; */
margin: 70rpx 30rpx 0 30rpx;
}
.progress-card__header {
display: flex;
align-items: flex-start;
justify-content: space-between;
}
.progress-card__profile {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.progress-card__avatar-shell {
width: 86rpx;
height: 86rpx;
padding: 3rpx;
box-sizing: border-box;
border-radius: 50%;
background: linear-gradient(180deg, rgba(255, 209, 153, 1), rgba(162, 119, 55, 1));
}
.progress-card__avatar {
width: 100%;
height: 100%;
display: block;
border-radius: 50%;
}
.progress-card__name {
width: 86rpx;
color: #E7BA80;
font-size: 18rpx;
line-height: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: center;
margin-top: 10rpx;
}
.progress-card__sound {
width: 68rpx;
height: 68rpx;
margin: 0;
padding: 0;
border: none;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: rgba(28, 24, 21, 0.72);
box-shadow: 0 8rpx 18rpx rgba(0, 0, 0, 0.18);
}
.progress-card__sound::after {
border: none;
}
.progress-card__sound-icon {
width: 34rpx;
height: 34rpx;
}
.progress-card__track-wrap {
margin-top: -156rpx;
padding-left: 102rpx;
}
.progress-card__titile{
width: 260rpx;
height: 72rpx;
margin-left: 110rpx;
}
.progress-card__track {
position: relative;
width: 100%;
height: 24rpx;
border-radius: 18rpx;
overflow: hidden;
background: #444444;
}
.progress-card__fill {
position: absolute;
top: 0;
left: 0;
bottom: 0;
border-radius: 18rpx;
background: linear-gradient( 133deg, #FFD19A 0%, #A17636 100%);
}
.progress-card__badge {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
min-width: 156rpx;
height: 40rpx;
padding: 0 24rpx;
box-sizing: border-box;
border-radius: 999rpx;
display: flex;
align-items: center;
justify-content: center;
/* background: rgba(164, 117, 47, 0.94); */
/* box-shadow: 0 4rpx 10rpx rgba(76, 45, 7, 0.22); */
}
.progress-card__badge-text {
color: #fff7de;
font-size: 18rpx;
line-height: 1;
white-space: nowrap;
}
.progress-card__tip {
display: block;
margin-top: 16rpx;
color: rgba(255, 243, 216, 0.88);
font-size: 24rpx;
line-height: 1.4;
text-align: center;
}
</style>