完成用新UI跑1v1

This commit is contained in:
kron
2025-08-14 10:50:44 +08:00
parent 670e79bea4
commit 6803d0f408
6 changed files with 294 additions and 60 deletions

View File

@@ -38,7 +38,7 @@ onMounted(() => {
}
if (
currentPage.route === "pages/battle-room" ||
currentPage.route === "pages/team-match" ||
currentPage.route === "pages/team-battle" ||
currentPage.route === "pages/melee-match"
) {
showLoader.value = true;

View File

@@ -7,42 +7,42 @@ import { storeToRefs } from "pinia";
const store = useStore();
const { user } = storeToRefs(store);
const tips = ref("请蓝队射击");
const tips = ref("");
const melee = ref(false);
const battleId = ref("");
const isMelee = ref("");
const timer = ref(null);
const sound = ref(true);
const currentSound = ref("");
const currentRound = ref(1);
const totalRound = ref(6);
const totalRound = ref(1);
const currentRoundEnded = ref(false);
const ended = ref(false);
const halfTime = ref(false);
// watch(
// () => props.tips,
// (newVal) => {
// let key = "";
// if (newVal.includes("红队")) key = "请红方射击";
// if (newVal.includes("蓝队")) key = "请蓝方射击";
// if (key && sound.value) {
// 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);
// }
// }
// }
// );
watch(
() => tips.value,
(newVal) => {
let key = "";
if (newVal.includes("红队")) key = "请红方射击";
if (newVal.includes("蓝队")) key = "请蓝方射击";
if (key && sound.value) {
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 updateSound = () => {
sound.value = !sound.value;
@@ -52,10 +52,7 @@ const updateSound = () => {
async function onReceiveMessage(messages = []) {
if (!sound.value || ended.value) return;
messages.forEach((msg) => {
if (
(battleId.value && msg.constructor === MESSAGETYPES.ShootResult) ||
(!battleId.value && msg.constructor === MESSAGETYPES.ShootSyncMeArrowID)
) {
if (battleId.value && msg.constructor === MESSAGETYPES.ShootResult) {
if (melee.value && msg.userId !== user.value.id) return;
if (!halfTime.value && msg.target) {
currentSound.value = msg.target.ring
@@ -63,12 +60,16 @@ async function onReceiveMessage(messages = []) {
: "未上靶";
audioManager.play(currentSound.value);
}
} else if (msg.constructor === MESSAGETYPES.WaitForAllReady) {
battleId.value = msg.id;
} else if (msg.constructor === MESSAGETYPES.AllReady) {
audioManager.play("比赛开始");
} else if (msg.constructor === MESSAGETYPES.MeleeAllReady) {
melee.value = true;
halfTime.value = false;
audioManager.play("比赛开始");
} else if (msg.constructor === MESSAGETYPES.CurrentRoundEnded) {
currentRound.value += 1;
currentRoundEnded.value = true;
} else if (msg.constructor === MESSAGETYPES.HalfTimeOver) {
halfTime.value = true;
@@ -90,12 +91,18 @@ const playSound = (key) => {
audioManager.play(key);
};
const onUpdateTips = (newVal) => {
tips.value = newVal;
};
onMounted(() => {
uni.$on("update-tips", onUpdateTips);
uni.$on("socket-inbox", onReceiveMessage);
uni.$on("play-sound", playSound);
});
onUnmounted(() => {
uni.$off("update-tips", onUpdateTips);
uni.$off("socket-inbox", onReceiveMessage);
uni.$off("play-sound", playSound);
if (timer.value) clearInterval(timer.value);
@@ -105,7 +112,7 @@ onUnmounted(() => {
<template>
<view class="container">
<text>{{ tips }}</text>
<text>({{ currentRound }}/{{ totalRound }})</text>
<!-- <text> ({{ currentRound }}/{{ totalRound }}) </text> -->
<button hover-class="none" @click="updateSound">
<image
:src="`../static/sound${sound ? '' : '-off'}-yellow.png`"

View File

@@ -34,7 +34,6 @@ watch(
if (remain.value > 0) remain.value--;
}, 1000);
}
console.log(barColor.value);
},
{
immediate: true,
@@ -44,11 +43,9 @@ watch(
const updateRemain = (value) => {
if (timer.value) clearInterval(timer.value);
remain.value = Math.round(value);
if (remain.value > 0) {
timer.value = setInterval(() => {
if (remain.value > 0) remain.value--;
}, 1000);
}
timer.value = setInterval(() => {
if (remain.value > 0) remain.value--;
}, 1000);
};
onMounted(() => {

View File

@@ -32,7 +32,7 @@ async function onReceiveMessage(messages = []) {
uni.removeStorageSync("current-battle");
if (gameType.value == 1) {
uni.redirectTo({
url: `/pages/team-match?battleId=${msg.id}&gameMode=2`,
url: `/pages/team-battle?battleId=${msg.id}&gameMode=2`,
});
} else if (gameType.value == 2) {
uni.redirectTo({

View File

@@ -21,7 +21,8 @@ import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
const { user } = storeToRefs(store);
const start = ref(true);
const start = ref(false);
const tips = ref("");
const battleId = ref("");
const currentRound = ref(1);
const currentRedPoint = ref(0);
@@ -31,19 +32,8 @@ const power = ref(0);
const scores = ref([]);
const blueScores = ref([]);
const redTeam = ref([]);
const blueTeam = ref([
{
name: "选手1",
},
{
name: "选手2",
},
{
name: "选手3",
},
]);
const blueTeam = ref([]);
const currentShooterId = ref(0);
const tips = ref("即将开始...");
const roundResults = ref([]);
const redPoints = ref(0);
const bluePoints = ref(0);
@@ -54,7 +44,218 @@ const isEnded = ref(false);
const onBack = () => {
uni.$showHint(2);
};
function onReceiveMessage() {}
function recoverData(battleInfo) {
uni.removeStorageSync("last-awake-time");
battleId.value = battleInfo.id;
redTeam.value = battleInfo.redTeam;
blueTeam.value = battleInfo.blueTeam;
if (battleInfo.status === 0) {
const readyRemain = Date.now() / 1000 - battleInfo.startTime;
console.log(`当前局已进行${readyRemain}`);
if (readyRemain > 0) {
setTimeout(() => {
uni.$emit("update-timer", 15 - readyRemain);
}, 200);
}
} else {
start.value = true;
bluePoints.value = 0;
redPoints.value = 0;
currentRound.value = battleInfo.currentRound;
totalRounds.value = battleInfo.maxRound;
roundResults.value = battleInfo.roundResults;
battleInfo.roundResults.forEach((round) => {
const blueTotal = round.blueArrows.reduce(
(last, next) => last + next.ring,
0
);
const redTotal = round.redArrows.reduce(
(last, next) => last + next.ring,
0
);
if (blueTotal === redTotal) {
bluePoints.value += 1;
redPoints.value += 1;
} else if (blueTotal > redTotal) {
bluePoints.value += 2;
} else {
redPoints.value += 2;
}
});
if (
battleInfo.redTeam[0].shotHistory[battleInfo.currentRound] ||
battleInfo.blueTeam[0].shotHistory[battleInfo.currentRound]
) {
roundResults.value.push({
redArrows: battleInfo.redTeam[0].shotHistory[
battleInfo.currentRound
].filter((item) => !!item.playerId),
blueArrows: battleInfo.blueTeam[0].shotHistory[
battleInfo.currentRound
].filter((item) => !!item.playerId),
});
} else if (battleInfo.currentRound < 5) {
roundResults.value.push({
redArrows: [],
blueArrows: [],
});
}
if (battleInfo.goldenRound) {
const { ShotCount, RedRecords, BlueRecords } = battleInfo.goldenRound;
const roundCount = Math.max(RedRecords.length, BlueRecords.length);
currentRound.value += roundCount;
isFinalShoot.value = true;
for (let i = 0; i < roundCount; i++) {
const roundData = {
redArrows:
RedRecords && RedRecords[i] ? RedRecords[i].Arrows || [] : [],
blueArrows:
BlueRecords && BlueRecords[i] ? BlueRecords[i].Arrows || [] : [],
};
if (roundResults.value[5 + i]) {
roundResults.value[5 + i] = roundData;
} else {
roundResults.value.push(roundData);
}
}
}
const lastIndex = roundResults.value.length - 1;
if (roundResults.value[lastIndex]) {
const redArrows = roundResults.value[lastIndex].redArrows;
scores.value = [...redArrows].filter((item) => !!item.playerId);
const blueArrows = roundResults.value[lastIndex].blueArrows;
blueScores.value = [...blueArrows].filter((item) => !!item.playerId);
}
// if (battleInfo.status !== 11) return;
if (battleInfo.firePlayerIndex) {
currentShooterId.value = battleInfo.firePlayerIndex;
// const teamPrefix =
// redTeam.value[0].id === currentShooterId.value
// ? "请红队射箭 - "
// : "请蓝队射箭 - ";
// const roundSuffix = isFinalShoot.value
// ? "决金箭"
// : `第${roundsName[currentRound.value]}轮`;
tips.value =
redTeam.value[0].id === currentShooterId.value
? "请红队射箭"
: "请蓝队射箭";
uni.$emit("update-tips", tips.value);
}
if (battleInfo.fireTime > 0) {
const remain = Date.now() / 1000 - battleInfo.fireTime;
console.log(`当前箭已过${remain}`);
if (remain > 0 && remain <= 15) {
// 等渲染好再通知
setTimeout(() => {
uni.$emit("update-ramain", 15 - remain);
}, 300);
}
}
}
}
async function onReceiveMessage(messages = []) {
messages.forEach((msg) => {
if (msg.constructor === MESSAGETYPES.AllReady) {
start.value = true;
totalRounds.value = msg.groupUserStatus.config.maxRounds;
roundResults.value = [
{
redArrows: [],
blueArrows: [],
},
];
}
if (msg.constructor === MESSAGETYPES.ToSomeoneShoot) {
if (currentShooterId.value !== msg.userId) {
currentShooterId.value = msg.userId;
// const teamPrefix =
// redTeam.value[0].id === currentShooterId.value
// ? "请红队射箭 - "
// : "请蓝队射箭 - ";
// const roundSuffix = isFinalShoot.value
// ? "决金箭"
// : `第${roundsName[currentRound.value]}轮`;
tips.value =
redTeam.value[0].id === currentShooterId.value
? "请红队射箭"
: "请蓝队射箭";
uni.$emit("update-tips", tips.value);
}
}
if (msg.constructor === MESSAGETYPES.ShootResult) {
if (currentShooterId.value !== msg.userId) return;
const isRed = redTeam.value.find((item) => item.id === msg.userId);
if (isRed) scores.value.push({ ...msg.target });
else blueScores.value.push({ ...msg.target });
if (!roundResults.value[currentRound.value - 1]) {
roundResults.value.push({
redArrows: [],
blueArrows: [],
});
}
roundResults.value[currentRound.value - 1][
isRed ? "redArrows" : "blueArrows"
].push({ ...msg.target });
}
if (msg.constructor === MESSAGETYPES.CurrentRoundEnded) {
const result = msg.preRoundResult;
scores.value = [];
blueScores.value = [];
currentShooterId.value = 0;
currentBluePoint.value = result.blueScore;
currentRedPoint.value = result.redScore;
bluePoints.value += result.blueScore;
redPoints.value += result.redScore;
if (result.currentRound < 5) {
currentRound.value = result.currentRound + 1;
roundResults.value.push({
redArrows: [],
blueArrows: [],
});
showRoundTip.value = true;
}
}
if (msg.constructor === MESSAGETYPES.FinalShoot) {
currentShooterId.value = 0;
currentRound.value += 1;
roundResults.value.push({
redArrows: [],
blueArrows: [],
});
if (!isFinalShoot.value) {
isFinalShoot.value = true;
showRoundTip.value = true;
tips.value = "准备开始决金箭";
}
}
if (msg.constructor === MESSAGETYPES.MatchOver) {
if (msg.endStatus.noSaved) {
currentRound.value += 1;
currentBluePoint.value = 0;
currentRedPoint.value = 0;
showRoundTip.value = true;
setTimeout(() => {
uni.navigateBack();
}, 3000);
} else {
isEnded.value = true;
uni.setStorageSync("last-battle", msg.endStatus);
setTimeout(() => {
uni.redirectTo({
url: "/pages/battle-result",
});
}, 1000);
}
}
if (msg.constructor === MESSAGETYPES.BackToGame) {
uni.$emit("update-header-loading", false);
if (msg.battleInfo) recoverData(msg.battleInfo);
}
});
}
onLoad(async (options) => {
if (options.battleId) {
@@ -82,6 +283,26 @@ onUnmounted(() => {
});
uni.$off("socket-inbox", onReceiveMessage);
});
const refreshTimer = ref(null);
onShow(async () => {
if (battleId.value) {
if (!isEnded.value && (await isGameEnded(battleId.value))) return;
getCurrentGameAPI();
const refreshData = () => {
const lastAwakeTime = uni.getStorageSync("last-awake-time");
if (lastAwakeTime) {
getCurrentGameAPI();
} else {
clearInterval(refreshTimer.value);
}
};
refreshTimer.value = setInterval(refreshData, 2000);
}
});
onHide(() => {
if (refreshTimer.value) clearInterval(refreshTimer.value);
uni.setStorageSync("last-awake-time", Date.now());
});
</script>
<template>
@@ -89,10 +310,19 @@ onUnmounted(() => {
<view class="container">
<BattleHeader v-if="!start" :redTeam="redTeam" :blueTeam="blueTeam" />
<TestDistance v-if="!start" :guide="false" />
<view class="players-row">
<TeamAvatars :team="blueTeam" :isRed="false" :youTurn="true" />
<ShootProgress2 :tips="tips" />
<TeamAvatars :team="blueTeam" :youTurn="true" />
<view v-if="start" class="players-row">
<TeamAvatars
:team="blueTeam"
:isRed="false"
:currentShooterId="currentShooterId"
:youTurn="true"
/>
<ShootProgress2 :tips="tips" :currentRound="'round' + currentRound" />
<TeamAvatars
:team="redTeam"
:currentShooterId="currentShooterId"
:youTurn="true"
/>
</view>
<BowTarget
v-if="start"

View File

@@ -55,7 +55,7 @@ function createWebSocket(token, onMessage) {
const currentPage = pages[pages.length - 1];
if (
currentPage.route === "pages/battle-room" ||
currentPage.route === "pages/team-match" ||
currentPage.route === "pages/team-battle" ||
currentPage.route === "pages/melee-match"
) {
return;
@@ -65,7 +65,7 @@ function createWebSocket(token, onMessage) {
console.log("----battleInfo", battleInfo);
if (battleInfo.config.mode === 1) {
uni.navigateTo({
url: `/pages/team-match?battleId=${battleInfo.id}&gameMode=${battleInfo.config.battleMode}`,
url: `/pages/team-battle?battleId=${battleInfo.id}&gameMode=${battleInfo.config.battleMode}`,
});
} else if (battleInfo.config.mode === 2) {
uni.navigateTo({