添加为上靶的方向指示

This commit is contained in:
kron
2025-11-12 16:14:48 +08:00
parent caadb5ea99
commit f41a3d7a3a
6 changed files with 140 additions and 24 deletions

View File

@@ -1,6 +1,7 @@
<script setup>
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
import { ref, watch, onMounted, onBeforeUnmount, computed } from "vue";
import StartCountdown from "@/components/StartCountdown.vue";
import { MESSAGETYPES } from "@/constants";
import { simulShootAPI } from "@/apis";
import useStore from "@/store";
import { storeToRefs } from "pinia";
@@ -42,12 +43,13 @@ const props = defineProps({
},
});
const showsimul = ref(false);
const latestOne = ref(null);
const bluelatestOne = ref(null);
const prevScores = ref([]);
const prevBlueScores = ref([]);
const timer = ref(null);
const dirTimer = ref(null);
const angle = ref(null);
watch(
() => props.scores,
@@ -98,10 +100,38 @@ const simulShoot2 = async () => {
if (device.value.deviceId) await simulShootAPI(device.value.deviceId, 1, 1);
};
onMounted(() => {
const env = computed(() => {
const accountInfo = uni.getAccountInfoSync();
const envVersion = accountInfo.miniProgram.envVersion;
if (envVersion !== "release") showsimul.value = true;
return accountInfo.miniProgram.envVersion;
});
const arrowStyle = computed(() => {
return {
transform: `rotateX(180deg) translate(-50%, -50%) rotate(${
360 - angle.value
}deg) translateY(100%)`,
};
});
async function onReceiveMessage(messages = []) {
messages.forEach((msg) => {
if (
msg.constructor === MESSAGETYPES.ShootSyncMeArrowID ||
msg.constructor === MESSAGETYPES.ShootResult
) {
if (msg.userId === user.value.id) {
angle.value =
!msg.target.ring && msg.target.angle >= 0 ? msg.target.angle : null;
dirTimer.value = setTimeout(() => {
angle.value = null;
}, 1200);
}
}
});
}
onMounted(() => {
uni.$on("socket-inbox", onReceiveMessage);
});
onBeforeUnmount(() => {
@@ -109,6 +139,11 @@ onBeforeUnmount(() => {
clearTimeout(timer.value);
timer.value = null;
}
if (dirTimer.value) {
clearTimeout(dirTimer.value);
dirTimer.value = null;
}
uni.$off("socket-inbox", onReceiveMessage);
});
</script>
@@ -122,6 +157,9 @@ onBeforeUnmount(() => {
}}</text>
</view>
<view class="target">
<view v-if="angle !== null" class="arrow-dir" :style="arrowStyle">
<image src="../static/arrow-direction.png" mode="widthFix" />
</view>
<view v-if="stop" class="stop-sign">中场休息</view>
<view
v-if="latestOne && latestOne.ring && user.id === latestOne.playerId"
@@ -206,7 +244,7 @@ onBeforeUnmount(() => {
<view v-if="avatar" class="footer">
<image :src="avatar" mode="widthFix" />
</view>
<view class="simul" v-if="showsimul">
<view class="simul" v-if="env !== 'release'">
<button @click="simulShoot">模拟</button>
<button @click="simulShoot2">射箭</button>
</view>
@@ -339,4 +377,24 @@ onBeforeUnmount(() => {
z-index: 99;
font-weight: bold;
}
@keyframes spring-in {
0% {
transform: translateY(-20px);
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
.arrow-dir {
position: absolute;
width: 36%;
left: 50%;
bottom: 50%;
}
.arrow-dir > image {
animation: spring-in 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
width: 100%;
}
</style>

View File

@@ -2,6 +2,8 @@
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
import audioManager from "@/audioManager";
import { MESSAGETYPES } from "@/constants";
import { getDirectionText } from "@/util";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
@@ -11,7 +13,6 @@ const tips = ref("");
const melee = ref(false);
const timer = ref(null);
const sound = ref(true);
const currentSound = ref("");
const currentRound = ref(0);
const currentRoundEnded = ref(false);
const ended = ref(false);
@@ -22,7 +23,6 @@ const totalShot = ref(0);
watch(
() => tips.value,
(newVal) => {
if (!sound.value) return;
let key = [];
if (newVal.includes("重回")) return;
if (currentRoundEnded.value) {
@@ -44,11 +44,11 @@ watch(
const updateSound = () => {
sound.value = !sound.value;
if (!sound.value) audioManager.stop(currentSound.value);
audioManager.setMuted(!sound.value);
};
async function onReceiveMessage(messages = []) {
if (!sound.value || ended.value) return;
if (ended.value) return;
messages.forEach((msg) => {
if (msg.constructor === MESSAGETYPES.ShootResult) {
if (melee.value && msg.userId !== user.value.id) return;
@@ -72,10 +72,11 @@ async function onReceiveMessage(messages = []) {
} catch (_) {}
}
if (!halfTime.value && msg.target) {
currentSound.value = msg.target.ring
? `${msg.target.ring}`
: "未上靶";
audioManager.play(currentSound.value);
let key = [];
key.push(msg.target.ring ? `${msg.target.ring}` : "未上靶");
if (!msg.target.ring)
key.push(`${getDirectionText(msg.target.angle)}调整`);
audioManager.play(key);
}
} else if (msg.constructor === MESSAGETYPES.InvalidShot) {
if (msg.userId === user.value.id) {
@@ -123,7 +124,6 @@ async function onReceiveMessage(messages = []) {
}
const playSound = (key) => {
currentSound.value = key;
audioManager.play(key);
};

View File

@@ -2,10 +2,13 @@
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
import audioManager from "@/audioManager";
import { MESSAGETYPES } from "@/constants";
import { getDirectionText } from "@/util";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
const { user } = storeToRefs(store);
const props = defineProps({
show: {
type: Boolean,
@@ -41,7 +44,6 @@ const barColor = ref("#fed847");
const remain = ref(props.total);
const timer = ref(null);
const sound = ref(true);
const currentSound = ref("");
const currentRound = ref(props.currentRound);
const currentRoundEnded = ref(false);
const ended = ref(false);
@@ -53,7 +55,7 @@ watch(
let key = "";
if (newVal.includes("红队")) key = "请红方射箭";
if (newVal.includes("蓝队")) key = "请蓝方射箭";
if (key && sound.value) {
if (key) {
if (currentRoundEnded.value) {
currentRound.value += 1;
currentRoundEnded.value = false;
@@ -118,11 +120,11 @@ const updateRemain = (value) => {
const updateSound = () => {
sound.value = !sound.value;
if (!sound.value) audioManager.stop(currentSound.value);
audioManager.setMuted(!sound.value);
};
async function onReceiveMessage(messages = []) {
if (!sound.value || ended.value) return;
if (ended.value) return;
messages.forEach((msg) => {
if (
(props.battleId && msg.constructor === MESSAGETYPES.ShootResult) ||
@@ -130,10 +132,11 @@ async function onReceiveMessage(messages = []) {
) {
if (props.melee && msg.userId !== user.value.id) return;
if (!halfTime.value && msg.target) {
currentSound.value = msg.target.ring
? `${msg.target.ring}`
: "未上靶";
audioManager.play(currentSound.value);
let key = [];
key.push(msg.target.ring ? `${msg.target.ring}` : "未上靶");
if (!msg.target.ring)
key.push(`${getDirectionText(msg.target.angle)}调整`);
audioManager.play(key);
}
} else if (msg.constructor === MESSAGETYPES.InvalidShot) {
if (msg.userId === user.value.id) {
@@ -164,7 +167,6 @@ async function onReceiveMessage(messages = []) {
}
const playSound = (key) => {
currentSound.value = key;
audioManager.play(key);
};