1v1流程调试完成

This commit is contained in:
kron
2025-06-05 21:32:51 +08:00
parent 58bd5d9bb2
commit 38019f1100
6 changed files with 313 additions and 152 deletions

View File

@@ -1,9 +1,18 @@
<script setup>
import Avatar from "@/components/Avatar.vue";
defineProps({
isMelee: {
type: Boolean,
default: false,
},
blueTeam: {
type: Array,
default: () => [],
},
redTeam: {
type: Array,
default: () => [],
},
});
</script>
@@ -18,18 +27,12 @@ defineProps({
</view>
<view v-if="!isMelee" class="players">
<view>
<view class="avatar">
<image src="../static/avatar-frame.png" mode="widthFix" />
<image src="../static/avatar.png" mode="widthFix" />
</view>
<text>选手1</text>
<Avatar v-if="blueTeam[0]" :src="blueTeam[0].avatar" frame />
<text>{{ blueTeam[0].name }}</text>
</view>
<view>
<view class="avatar">
<image src="../static/avatar-frame.png" mode="widthFix" />
<image src="../static/avatar.png" mode="widthFix" />
</view>
<text>选手2</text>
<Avatar v-if="redTeam[0]" :src="redTeam[0].avatar" frame />
<text>{{ redTeam[0].name }}</text>
</view>
</view>
</view>
@@ -59,6 +62,7 @@ defineProps({
color: #fff9;
font-size: 14px;
padding-top: 20px;
overflow: hidden;
}
.players > view:first-child {
background-color: #364469;
@@ -66,21 +70,4 @@ defineProps({
.players > view:last-child {
background-color: #692735;
}
.avatar {
position: relative;
display: flex;
align-items: center;
justify-content: center;
margin: 5px 0;
}
.avatar > image:first-child {
position: absolute;
width: 55px;
height: 55px;
}
.avatar > image {
width: 45px;
height: 45px;
border-radius: 50%;
}
</style>

View File

@@ -12,15 +12,22 @@ defineProps({
type: Array,
default: () => [],
},
currentShooterId: {
type: Number,
default: 0,
},
});
</script>
<template>
<view class="container">
<image v-if="avatar" class="avatar" :src="avatar" mode="widthFix" />
<view v-if="!avatar" :style="{ height: 20 + blueTeam.length * 20 + 'px' }">
<view
v-if="blueTeam.length && redTeam.length"
:style="{ height: 20 + blueTeam.length * 20 + 'px' }"
>
<view
v-for="(item, index) in blueTeam"
v-for="(player, index) in blueTeam"
:key="index"
:style="{
top: index * 20 + 'px',
@@ -30,51 +37,52 @@ defineProps({
>
<image
class="avatar"
:src="item.avatar"
:src="player.avatar"
mode="widthFix"
:style="{
borderColor: index === 0 ? '#5fadff' : '#fff',
borderColor: currentShooterId === player.id ? '#5fadff' : '#fff',
}"
/>
<text
:style="{
color: index === 0 ? '#5fadff' : '#fff',
fontSize: index === 0 ? 16 : 12 + 'px',
color: currentShooterId === player.id ? '#5fadff' : '#fff',
fontSize: currentShooterId === player.id ? 16 : 12 + 'px',
}"
>
{{ item.name }}
{{ player.name }}
</text>
</view>
</view>
<view
v-if="!avatar"
:style="{
height: 20 + blueTeam.length * 20 + 'px',
height: 20 + redTeam.length * 20 + 'px',
}"
>
<view
v-for="(item, index) in blueTeam"
v-for="(player, index) in redTeam"
:key="index"
:style="{
top: index * 20 + 'px',
zIndex: blueTeam.length - index,
zIndex: redTeam.length - index,
right: 0,
}"
>
<text
:style="{
color: index === 0 ? '#ff6060' : '#fff',
fontSize: index === 0 ? 16 : 12 + 'px',
color: currentShooterId === player.id ? '#ff6060' : '#fff',
fontSize: currentShooterId === player.id ? 16 : 12 + 'px',
textAlign: 'right',
}"
>
{{ item.name }}
{{ player.name }}
</text>
<image
class="avatar"
:src="item.avatar"
:src="player.avatar"
mode="widthFix"
:style="{
borderColor: index === 0 ? '#ff6060' : '#fff',
borderColor: currentShooterId === player.id ? '#ff6060' : '#fff',
}"
/>
</view>
@@ -104,6 +112,8 @@ defineProps({
}
.container > view > view > text {
margin: 0 10px;
overflow: hidden;
width: 100px;
}
.avatar {
width: 40px;

View File

@@ -13,23 +13,43 @@ const props = defineProps({
type: Number,
default: 90,
},
seq: {
type: Number,
default: 0,
},
});
let barColor = "#fed847";
if (props.tips.includes("红队")) barColor = "#FF6060";
if (props.tips.includes("蓝队")) barColor = "#5FADFF";
const remain = ref(props.total);
const timer = ref(null);
watch(
() => props.seq,
() => {
if (timer.value) clearInterval(timer.value);
remain.value = props.total;
timer.value = setInterval(() => {
if (remain.value > 0) {
remain.value--;
}
}, 1000);
}
);
watch(
() => props.start,
(newVal, oldVal) => {
if (oldVal === false && newVal === true) {
remain.value = props.total;
setInterval(() => {
timer.value = setInterval(() => {
if (remain.value > 0) {
remain.value--;
}
}, 1000);
} else {
if (timer.value) clearInterval(timer.value);
}
}
);

86
src/components/Timer.vue Normal file
View File

@@ -0,0 +1,86 @@
<script setup>
import { ref, watch } from "vue";
const props = defineProps({
seq: {
type: Number,
default: 0,
},
countdown: {
type: Number,
default: 15,
},
callBack: {
type: Function,
default: () => {},
},
});
const show = ref(false);
const count = ref(0);
const timer = ref(null);
watch(
() => props.seq,
() => {
if (props.seq > 0) {
if(show.value) return;
if (timer.value) clearInterval(timer.value);
count.value = props.countdown;
show.value = true;
timer.value = setInterval(() => {
if (count.value === 0) {
show.value = false;
clearInterval(timer.value);
props.callBack();
} else {
count.value -= 1;
}
}, 1000);
} else {
if (timer.value) clearInterval(timer.value);
show.value = false;
}
}
);
</script>
<template>
<view
class="container"
:style="{ transform: `translateX(${show ? '0' : '100'}%)` }"
>
<view>距离正式比赛</view>
<view>
<text>开始还有</text>
<text>{{ count }}</text>
<text></text>
</view>
</view>
</template>
<style scoped>
.container {
transform: translateX(100%);
position: fixed;
bottom: 20%;
right: 0;
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: flex-start;
color: #fff9;
font-size: 14px;
padding: 10px;
background-color: #00000066;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
}
.container > view {
display: flex;
align-items: center;
}
.container > view:last-child > text:nth-child(2) {
color: #fed847;
font-size: 16px;
width: 16px;
text-align: center;
}
</style>