Merge branch 'new-race-mode' into test

This commit is contained in:
2026-05-11 15:17:06 +08:00
3 changed files with 52 additions and 12 deletions

View File

@@ -36,7 +36,14 @@ const updateRemain = (value) => {
if (value.team === 'blue') if (value.team === 'blue')
barColor.value = "linear-gradient( 180deg, #9AB3FF 0%, #4288FF 100%)"; barColor.value = "linear-gradient( 180deg, #9AB3FF 0%, #4288FF 100%)";
if (value.reset) { if (value.reset) {
// 重置前先清除旧计时器,防止超时未射箭时旧 interval 残留,导致进度条震荡
if (timer.value) clearInterval(timer.value);
// 重置时瞬间跳满格,禁用 CSS 过渡避免从旧值「涨到满」的动画
transitionStyle.value = "none";
remain.value = value.value; remain.value = value.value;
setTimeout(() => {
transitionStyle.value = "all 1s linear";
}, 50);
return; return;
} }
const newVal = Math.round(value.value); const newVal = Math.round(value.value);
@@ -51,6 +58,8 @@ const updateRemain = (value) => {
remain.value = newVal; remain.value = newVal;
} }
// 启动前先清除旧计时器,防止多次 {stop:false} 事件叠加多个 interval
if (timer.value) clearInterval(timer.value);
timer.value = setInterval(() => { timer.value = setInterval(() => {
loading.value = remain.value === 0; loading.value = remain.value === 0;
if (remain.value > 0) remain.value--; if (remain.value > 0) remain.value--;

View File

@@ -26,13 +26,15 @@ async function onReceiveMessage(msg) {
onComplete.value = () => {} onComplete.value = () => {}
} }
if (msg.type === MESSAGETYPESV2.AboutToStart) { if (msg.type === MESSAGETYPESV2.AboutToStart) {
if (gameType.value == 1) { // 使用后端下发的 mode 字段判断跳转目标与好友约战battle-room.vue保持一致
// mode <= 3 为团队对抗mode > 3 为大乱斗,覆盖全部 gameType1~5不再遗漏
if (msg.mode <= 3) {
uni.redirectTo({ uni.redirectTo({
url: `/pages/team-battle?battleId=${msg.id}&gameMode=2`, url: `/pages/team-battle?battleId=${msg.id}`,
}); });
} else if (gameType.value == 2) { } else {
uni.redirectTo({ uni.redirectTo({
url: `/pages/melee-battle?battleId=${msg.id}&gameMode=2`, url: `/pages/melee-battle?battleId=${msg.id}`,
}); });
} }
} }

View File

@@ -23,6 +23,8 @@ const start = ref(null);
const tips = ref(""); const tips = ref("");
const battleId = ref(""); const battleId = ref("");
const currentRound = ref(0); const currentRound = ref(0);
/** 专用于 RoundEndTip 展示的轮次,与进度条的 currentRound 解耦,避免 ToSomeoneShoot 提前更新 currentRound 导致 Tip 显示错误轮次 */
const roundTipRound = ref(0);
const goldenRound = ref(0); const goldenRound = ref(0);
const currentRedPoint = ref(0); const currentRedPoint = ref(0);
const currentBluePoint = ref(0); const currentBluePoint = ref(0);
@@ -75,6 +77,8 @@ const recoverData = (battleInfo, {force = false, arrowOnly = false} = {}) => {
return; return;
} }
if (!arrowOnly) { if (!arrowOnly) {
// 在 ToSomeoneShoot 时同步更新当前轮次,使进度条轮次图片及时切换
currentRound.value = battleInfo.current.round || 1;
currentShooterId.value = battleInfo.current.playerId; currentShooterId.value = battleInfo.current.playerId;
const redPlayer = battleInfo.teams[2].players.find( const redPlayer = battleInfo.teams[2].players.find(
(item) => item.id === battleInfo.current.playerId (item) => item.id === battleInfo.current.playerId
@@ -87,9 +91,17 @@ const recoverData = (battleInfo, {force = false, arrowOnly = false} = {}) => {
) { ) {
nextTips += "你"; nextTips += "你";
} }
// 同队连续出手时 tips 值不变HeaderProgress watch 不触发音频
// 需在赋值前比较旧值,手动播放音频确保始终触发 onAudioEnded 启动计时器
// 注意:使用 interrupt=false 避免打断上一支箭的环数播报音频
if (tips.value === nextTips && !nextTips.includes("重回")) {
const audioKey = redPlayer ? "请红方射箭" : "请蓝方射箭";
audioManager.play(audioKey, false);
}
tips.value = nextTips; tips.value = nextTips;
uni.$emit("update-tips", nextTips); uni.$emit("update-tips", nextTips);
uni.$emit("update-remain", {reset: true, value: 15, team: redTeam?'red':'blue'}); // redPlayer 已在上方 find() 确认:不为 null 则当前射手在红队
uni.$emit("update-remain", {reset: true, value: 15, team: redPlayer?'red':'blue'});
if (force) { if (force) {
const remain = (Date.now() - battleInfo.current.startTime) / 1000; const remain = (Date.now() - battleInfo.current.startTime) / 1000;
console.log(`当前轮已进行${remain}`); console.log(`当前轮已进行${remain}`);
@@ -117,8 +129,13 @@ const recoverData = (battleInfo, {force = false, arrowOnly = false} = {}) => {
}; };
function onAudioEnded(s) { function onAudioEnded(s) {
if (s.indexOf('请红方射箭') >= 0 || s.indexOf('请蓝方射箭') >= 0) { // "请红方射箭"/"请蓝方射箭":队友或对手轮次;"轮到你了"用户本人轮次HeaderProgress特殊分支
let team = s.indexOf('请红方射箭') >= 0 ? 'red' : 'blue'; // 三者音频结束后均需启动倒计时进度条
if (s.indexOf('请红方射箭') >= 0 || s.indexOf('请蓝方射箭') >= 0 || s.indexOf('轮到你了') >= 0) {
let team;
if (s.indexOf('请红方射箭') >= 0) team = 'red';
else if (s.indexOf('请蓝方射箭') >= 0) team = 'blue';
else team = tips.value.includes('红队') ? 'red' : 'blue'; // 轮到你了从当前tips判断用户所在队伍
uni.$emit("update-remain", {stop: false, value: updateRemainSecond.value, team: team}); uni.$emit("update-remain", {stop: false, value: updateRemainSecond.value, team: team});
} }
if (s.indexOf("比赛结束") >= 0) { if (s.indexOf("比赛结束") >= 0) {
@@ -136,10 +153,20 @@ function onBattleEnd() {
} }
} }
function onNewRound(msg) { /**
* @param {object} msg - NewRound 消息
* @param {number} prevRound - 在 NewRound 消息到达时即时捕获的旧轮次,用于 Tip 展示,避免异步延迟内 currentRound 已被更新
*/
function onNewRound(msg, prevRound) {
showRoundTip.value = true; showRoundTip.value = true;
isFinalShoot.value = msg.current.goldRound; isFinalShoot.value = msg.current.goldRound;
const latestRound = msg.rounds[currentRound.value - 1]; // 决金箭轮每人只射一箭,重置箭数显示为 (0/1)
if (msg.current.goldRound) {
uni.$emit("update-shot", { currentShot: 0, totalShot: 1 });
}
// 用传入的 prevRound捕获时刻的旧轮次展示结算 Tip与进度条 currentRound 解耦
roundTipRound.value = prevRound;
const latestRound = msg.rounds[prevRound - 1];
if (latestRound) { if (latestRound) {
if (isFinalShoot.value) { if (isFinalShoot.value) {
currentBluePoint.value = msg.teams[1].score; currentBluePoint.value = msg.teams[1].score;
@@ -162,8 +189,10 @@ async function onReceiveMessage(msg) {
showRoundTip.value = false; showRoundTip.value = false;
recoverData(msg, {arrowOnly: true}); recoverData(msg, {arrowOnly: true});
} else if (msg.type === MESSAGETYPESV2.NewRound) { } else if (msg.type === MESSAGETYPESV2.NewRound) {
// 在进入延迟前先捕获当前轮次,供 onNewRound 使用,防止 800ms 内 ToSomeoneShoot 提前更新 currentRound 造成 Tip 展示错轮
const prevRound = currentRound.value;
setTimeout(() => { setTimeout(() => {
onNewRound(msg) onNewRound(msg, prevRound)
}, 800) }, 800)
} else if (msg.type === MESSAGETYPESV2.BattleEnd) { } else if (msg.type === MESSAGETYPESV2.BattleEnd) {
matchStatus.value = msg.status; matchStatus.value = msg.status;
@@ -263,11 +292,11 @@ onShow(async () => {
<RoundEndTip <RoundEndTip
v-if="showRoundTip" v-if="showRoundTip"
:isFinal="isFinalShoot" :isFinal="isFinalShoot"
:round="currentRound" :round="roundTipRound"
:bluePoint="currentBluePoint" :bluePoint="currentBluePoint"
:redPoint="currentRedPoint" :redPoint="currentRedPoint"
:roundData=" :roundData="
roundResults[currentRound - 1] ? roundResults[currentRound - 1] : [] roundResults[roundTipRound - 1] ? roundResults[roundTipRound - 1] : []
" "
:onAutoClose="()=>{ showRoundTip = false}" :onAutoClose="()=>{ showRoundTip = false}"
/> />