diff --git a/project.config.json b/project.config.json
index f6d496c..0ffafb0 100644
--- a/project.config.json
+++ b/project.config.json
@@ -3,7 +3,240 @@
"compileType": "miniprogram",
"libVersion": "3.7.7",
"packOptions": {
- "ignore": [],
+ "ignore": [
+ {
+ "type": "file",
+ "value": "static/common/dialog-light.png"
+ },
+ {
+ "type": "file",
+ "value": "static/common/dialog-bg.png"
+ },
+ {
+ "type": "file",
+ "value": "static/common/dialog-icon.png"
+ },
+ {
+ "type": "file",
+ "value": "static/prompt-bg-square.png"
+ },
+ {
+ "type": "file",
+ "value": "static/coach-comment.png"
+ },
+ {
+ "type": "file",
+ "value": "static/screen-hint-bg.png"
+ },
+ {
+ "type": "file",
+ "value": "static/red-team-win.png"
+ },
+ {
+ "type": "file",
+ "value": "static/blue-team-win.png"
+ },
+ {
+ "type": "file",
+ "value": "static/my-grow.png"
+ },
+ {
+ "type": "file",
+ "value": "static/gold-shining.png"
+ },
+ {
+ "type": "file",
+ "value": "static/bow-target.png"
+ },
+ {
+ "type": "file",
+ "value": "static/matching-bg.png"
+ },
+ {
+ "type": "file",
+ "value": "static/versus.png"
+ },
+ {
+ "type": "file",
+ "value": "static/point-champion.png"
+ },
+ {
+ "type": "file",
+ "value": "static/my-practise.png"
+ },
+ {
+ "type": "file",
+ "value": "static/shining-bg.png"
+ },
+ {
+ "type": "file",
+ "value": "static/donate.png"
+ },
+ {
+ "type": "file",
+ "value": "static/friend-battle.png"
+ },
+ {
+ "type": "file",
+ "value": "static/user-upgrade.png"
+ },
+ {
+ "type": "file",
+ "value": "static/finish-frame.png"
+ },
+ {
+ "type": "file",
+ "value": "static/vip/svip-jian.png"
+ },
+ {
+ "type": "file",
+ "value": "static/battle-header.png"
+ },
+ {
+ "type": "file",
+ "value": "static/battle-header-melee.png"
+ },
+ {
+ "type": "file",
+ "value": "static/player-bg.png"
+ },
+ {
+ "type": "file",
+ "value": "static/mvp-blue.png"
+ },
+ {
+ "type": "file",
+ "value": "static/finish-tip.png"
+ },
+ {
+ "type": "file",
+ "value": "static/2unfinish-tip.png"
+ },
+ {
+ "type": "file",
+ "value": "static/have-no-device.png"
+ },
+ {
+ "type": "file",
+ "value": "static/device-icon.png"
+ },
+ {
+ "type": "file",
+ "value": "static/unfinish-tip.png"
+ },
+ {
+ "type": "file",
+ "value": "static/test-tip.png"
+ },
+ {
+ "type": "file",
+ "value": "static/mvp-red.png"
+ },
+ {
+ "type": "file",
+ "value": "static/vip/svip-lie.png"
+ },
+ {
+ "type": "file",
+ "value": "static/mvp-tip.png"
+ },
+ {
+ "type": "file",
+ "value": "static/rank/battle-choose.png"
+ },
+ {
+ "type": "file",
+ "value": "static/back-to-game-bg.png"
+ },
+ {
+ "type": "file",
+ "value": "static/complete-light1.png"
+ },
+ {
+ "type": "file",
+ "value": "static/complete-light2.png"
+ },
+ {
+ "type": "file",
+ "value": "static/title-2v2.png"
+ },
+ {
+ "type": "file",
+ "value": "static/tab-bg.png"
+ },
+ {
+ "type": "file",
+ "value": "static/scan.png"
+ },
+ {
+ "type": "file",
+ "value": "static/choose-battle-mode.png"
+ },
+ {
+ "type": "file",
+ "value": "static/shooter.png"
+ },
+ {
+ "type": "file",
+ "value": "static/my-growth.png"
+ },
+ {
+ "type": "file",
+ "value": "static/juezhanbang.png"
+ },
+ {
+ "type": "file",
+ "value": "static/title-3v3.png"
+ },
+ {
+ "type": "file",
+ "value": "static/point-book-tip-bg.png"
+ },
+ {
+ "type": "file",
+ "value": "static/reward-us.png"
+ },
+ {
+ "type": "file",
+ "value": "static/rank/star.png"
+ },
+ {
+ "type": "file",
+ "value": "static/tab-point-book.png"
+ },
+ {
+ "type": "file",
+ "value": "static/pk-icon.png"
+ },
+ {
+ "type": "file",
+ "value": "static/first-try.png"
+ },
+ {
+ "type": "file",
+ "value": "static/row-yellow-bg.png"
+ },
+ {
+ "type": "file",
+ "value": "static/room-notfound-title.png"
+ },
+ {
+ "type": "file",
+ "value": "static/title-mvp.png"
+ },
+ {
+ "type": "file",
+ "value": "static/long-bubble-tall.png"
+ },
+ {
+ "type": "file",
+ "value": "static/battle-result.png"
+ },
+ {
+ "type": "file",
+ "value": "static/tab-mall.png"
+ }
+ ],
"include": []
},
"setting": {
diff --git a/src/apis.js b/src/apis.js
index 867dacc..baeff6a 100644
--- a/src/apis.js
+++ b/src/apis.js
@@ -8,8 +8,8 @@ try {
switch (envVersion) {
case "develop": // 开发版
- // BASE_URL = "http://192.168.1.2:8000/api/shoot";
- BASE_URL = "https://apitest.shelingxingqiu.com/api/shoot";
+ BASE_URL = "http://192.168.1.2:8000/api/shoot";
+ // BASE_URL = "https://apitest.shelingxingqiu.com/api/shoot";
break;
case "trial": // 体验版
BASE_URL = "https://apitest.shelingxingqiu.com/api/shoot";
@@ -26,6 +26,7 @@ try {
}
const ADDONS_BASE_URL = BASE_URL.replace(/\/api\/shoot$/, "/api/shoot");
+const PRACTICE_BASE_URL = BASE_URL.replace(/\/api\/shoot$/, "/api");
// 统一处理业务接口请求,包含登录态、业务错误和 WiFi 连接空响应兼容。
function request(method, url, data = {}, baseUrl = BASE_URL) {
@@ -263,6 +264,15 @@ export const createPractiseAPI = (arrows, time, target) => {
});
};
+export const createPractiseV2API = (arrows, time, target, deviceId) => {
+ return request("POST", "/practice/create-v2", {
+ shootNumber: arrows,
+ shootTime: time,
+ targetType: Number(target || 1) * 20,
+ deviceId,
+ }, PRACTICE_BASE_URL);
+};
+
export const startPractiseAPI = () => {
return request("POST", "/user/practice/begin");
};
diff --git a/src/components/AppFooter.vue b/src/components/AppFooter.vue
index bfe2831..f65b8fc 100644
--- a/src/components/AppFooter.vue
+++ b/src/components/AppFooter.vue
@@ -1,8 +1,8 @@
-
+
{
diff --git a/src/components/ModalDialog.vue b/src/components/ModalDialog.vue
index 069a0f3..5ab17a6 100644
--- a/src/components/ModalDialog.vue
+++ b/src/components/ModalDialog.vue
@@ -52,19 +52,19 @@ const handleConfirm = () => {
diff --git a/src/components/PlayerSeats.vue b/src/components/PlayerSeats.vue
index 5ce4f2a..5b029f8 100644
--- a/src/components/PlayerSeats.vue
+++ b/src/components/PlayerSeats.vue
@@ -26,7 +26,7 @@ const seats = new Array(props.total).fill(1);
-
+
{
-
+
{{ data.actualTotalRing }}
/
diff --git a/src/components/RewardUs.vue b/src/components/RewardUs.vue
index b3be27f..dd28005 100644
--- a/src/components/RewardUs.vue
+++ b/src/components/RewardUs.vue
@@ -93,7 +93,7 @@ onMounted(async () => {
-
+
感谢您对我们公益项目的支持!
-
+
{
toPage('/pages/my-growth')">
-
+
toPage('/pages/ranking')">
diff --git a/src/pages/melee-bow-data.vue b/src/pages/melee-bow-data.vue
index e3892f6..b171477 100644
--- a/src/pages/melee-bow-data.vue
+++ b/src/pages/melee-bow-data.vue
@@ -65,7 +65,7 @@ onLoad(async (options) => {
diff --git a/src/pages/my-device.vue b/src/pages/my-device.vue
index 94a7588..c0aab72 100644
--- a/src/pages/my-device.vue
+++ b/src/pages/my-device.vue
@@ -161,7 +161,7 @@ onShow(async () => {
-
+
扫
@@ -172,7 +172,7 @@ onShow(async () => {
射灵智能弓箭,三模传感系统与独创靶环算法,
毫秒级在线实时对战,让你拥有全球约战的乐趣!
-
+
{
:style="{ marginBottom: calibration ? '250rpx' : '100rpx' }"
>
-
+
{{ device.deviceName }}
@@ -286,7 +286,7 @@ onShow(async () => {
-
+
{{ device.deviceName }}
diff --git a/src/pages/point-book-rank.vue b/src/pages/point-book-rank.vue
index 2df8bda..68de914 100644
--- a/src/pages/point-book-rank.vue
+++ b/src/pages/point-book-rank.vue
@@ -44,7 +44,7 @@ onMounted(async () => {
-
+
{
/>
{
-
+
diff --git a/src/pages/practise-one.vue b/src/pages/practise-one.vue
index a779994..6b9ed21 100644
--- a/src/pages/practise-one.vue
+++ b/src/pages/practise-one.vue
@@ -15,10 +15,9 @@ import audioManager from "@/audioManager";
import {
createPractiseAPI,
- startPractiseAPI,
- endPractiseAPI,
getPractiseAPI,
} from "@/apis";
+import { connectMatchWebSocket, closeMatchWebSocket } from "@/matchWebsocket";
import { sharePractiseData } from "@/canvas";
import { wxShare, debounce } from "@/util";
import { MESSAGETYPESV2, roundsName } from "@/constants";
@@ -26,7 +25,7 @@ import { MESSAGETYPESV2, roundsName } from "@/constants";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
-const { user } = storeToRefs(store);
+const { user, device } = storeToRefs(store);
const start = ref(false);
const scores = ref([]);
@@ -40,6 +39,7 @@ const showGuide = ref(false);
const tips = ref("");
const targetType = ref(1);
const sharing = ref(false);
+const RESULT_TIP_CDN = "https://static.shelingxingqiu.com/shootmini/static";
onLoad((options) => {
if (options.target) {
@@ -47,8 +47,31 @@ onLoad((options) => {
}
});
+const createPractise = async () => {
+ closeMatchWebSocket({ reason: "practice-recreate" });
+ const result = await createPractiseAPI(
+ total,
+ 120,
+ targetType.value,
+ device.value.deviceId
+ );
+ if (result?.id) practiseId.value = result.id;
+ if (!result?.serverAddr) {
+ uni.showToast({
+ title: "练习连接信息异常,请重试",
+ icon: "none",
+ });
+ return null;
+ }
+ connectMatchWebSocket({
+ serverAddr: result.serverAddr,
+ matchId: result.id,
+ userId: user.value.id,
+ });
+ return result;
+};
+
const onReady = async () => {
- await startPractiseAPI();
scores.value = [];
isSvip.value = false;
xRingStreak.value = 0; // 新一局开始,重置 X 环连续计数
@@ -56,8 +79,10 @@ const onReady = async () => {
audioManager.play("练习开始");
};
-const onOver = async () => {
- practiseResult.value = await getPractiseAPI(practiseId.value);
+const onOver = async (message) => {
+ practiseResult.value = Array.isArray(message?.details)
+ ? message
+ : await getPractiseAPI(practiseId.value);
start.value = false;
};
@@ -87,14 +112,14 @@ async function onReceiveMessage(msg) {
if (msg.type === MESSAGETYPESV2.ShootResult) {
const prevLen = scores.value.length;
isSvip.value = msg.sVip === true;
- scores.value = msg.details;
+ scores.value = Array.isArray(msg.details) ? msg.details : scores.value;
// 有新箭时取最后一箭判断是否 10 环及以上并检测连续计数
if (scores.value.length > prevLen) {
const latestArrow = scores.value[scores.value.length - 1];
checkAndPlayTententen(isTenPlusRing(latestArrow));
}
} else if (msg.type === MESSAGETYPESV2.BattleEnd) {
- // setTimeout(onOver, 1500);
+ setTimeout(() => onOver(msg), 1500);
}
}
@@ -111,11 +136,17 @@ async function onComplete() {
scores.value = [];
isSvip.value = false;
xRingStreak.value = 0; // 重新开始练习,重置 X 环连续计数
- const result = await createPractiseAPI(total, 120);
- if (result) practiseId.value = result.id;
+ await createPractise();
}
}
+const getResultTipSrc = (result = {}) => {
+ const validCount = (result.details || []).filter(
+ (arrow) => arrow.x !== -30 && arrow.y !== -30
+ ).length;
+ return `${RESULT_TIP_CDN}/${validCount < total ? "un" : ""}finish-tip.png`;
+};
+
const onClickShare = debounce(async () => {
if (sharing.value) return;
sharing.value = true;
@@ -132,12 +163,6 @@ const onClickShare = debounce(async () => {
}
});
-function onAudioEnded(s) {
- if (s.indexOf("比赛结束") >= 0) {
- onOver()
- }
-}
-
onMounted(async () => {
// audioManager.play("第一轮");
uni.setKeepScreenOn({
@@ -145,9 +170,7 @@ onMounted(async () => {
});
uni.$on("socket-inbox", onReceiveMessage);
uni.$on("share-image", onClickShare);
- uni.$on("audioEnded", onAudioEnded);
- const result = await createPractiseAPI(total, 120, targetType.value);
- if (result) practiseId.value = result.id;
+ await createPractise();
});
onBeforeUnmount(() => {
@@ -156,9 +179,8 @@ onBeforeUnmount(() => {
});
uni.$off("socket-inbox", onReceiveMessage);
uni.$off("share-image", onClickShare);
- uni.$off("audioEnded", onAudioEnded);
audioManager.stopAll();
- endPractiseAPI();
+ closeMatchWebSocket({ reason: "practice-leave" });
});
@@ -203,13 +225,7 @@ onBeforeUnmount(() => {
:total="total"
:onClose="onComplete"
:result="practiseResult"
- :tipSrc="`../static/${
- practiseResult.details.filter(
- (arrow) => arrow.x !== -30 && arrow.y !== -30
- ).length < total
- ? 'un'
- : ''
- }finish-tip.png`"
+ :tipSrc="getResultTipSrc(practiseResult)"
/>
diff --git a/src/pages/practise-two.vue b/src/pages/practise-two.vue
index 7f6cac4..5113f9d 100644
--- a/src/pages/practise-two.vue
+++ b/src/pages/practise-two.vue
@@ -14,10 +14,9 @@ import audioManager from "@/audioManager";
import {
createPractiseAPI,
- startPractiseAPI,
- endPractiseAPI,
getPractiseAPI,
} from "@/apis";
+import { connectMatchWebSocket, closeMatchWebSocket } from "@/matchWebsocket";
import { sharePractiseData } from "@/canvas";
import { wxShare, debounce } from "@/util";
import { MESSAGETYPESV2 } from "@/constants";
@@ -26,7 +25,7 @@ import useStore from "@/store";
import { storeToRefs } from "pinia";
import {onLoad} from "@dcloudio/uni-app";
const store = useStore();
-const { user } = storeToRefs(store);
+const { user, device } = storeToRefs(store);
const start = ref(false);
const scores = ref([]);
@@ -39,6 +38,7 @@ const practiseId = ref("");
const showGuide = ref(false);
const targetType = ref(1);
const sharing = ref(false);
+const RESULT_TIP_CDN = "https://static.shelingxingqiu.com/shootmini/static";
onLoad((options) => {
if (options.target) {
@@ -46,8 +46,31 @@ onLoad((options) => {
}
});
+const createPractise = async () => {
+ closeMatchWebSocket({ reason: "practice-recreate" });
+ const result = await createPractiseAPI(
+ total,
+ 3600,
+ targetType.value,
+ device.value.deviceId
+ );
+ if (result?.id) practiseId.value = result.id;
+ if (!result?.serverAddr) {
+ uni.showToast({
+ title: "练习连接信息异常,请重试",
+ icon: "none",
+ });
+ return null;
+ }
+ connectMatchWebSocket({
+ serverAddr: result.serverAddr,
+ matchId: result.id,
+ userId: user.value.id,
+ });
+ return result;
+};
+
const onReady = async () => {
- await startPractiseAPI();
scores.value = [];
isSvip.value = false;
xRingStreak.value = 0; // 新一局开始,重置 X 环连续计数
@@ -55,8 +78,10 @@ const onReady = async () => {
audioManager.play("练习开始");
};
-const onOver = async () => {
- practiseResult.value = await getPractiseAPI(practiseId.value);
+const onOver = async (message) => {
+ practiseResult.value = Array.isArray(message?.details)
+ ? message
+ : await getPractiseAPI(practiseId.value);
start.value = false;
};
@@ -86,14 +111,14 @@ async function onReceiveMessage(msg) {
if (msg.type === MESSAGETYPESV2.ShootResult) {
const prevLen = scores.value.length;
isSvip.value = msg.sVip === true;
- scores.value = msg.details;
+ scores.value = Array.isArray(msg.details) ? msg.details : scores.value;
// 有新箭时取最后一箭判断是否 10 环及以上并检测连续计数
if (scores.value.length > prevLen) {
const latestArrow = scores.value[scores.value.length - 1];
checkAndPlayTententen(isTenPlusRing(latestArrow));
}
} else if (msg.type === MESSAGETYPESV2.BattleEnd) {
- setTimeout(onOver, 1500);
+ setTimeout(() => onOver(msg), 1500);
}
// messages.forEach((msg) => {
// if (msg.constructor === MESSAGETYPES.ShootSyncMeArrowID) {
@@ -126,11 +151,17 @@ async function onComplete() {
scores.value = [];
isSvip.value = false;
xRingStreak.value = 0; // 重新开始练习,重置 X 环连续计数
- const result = await createPractiseAPI(total, 3600);
- if (result) practiseId.value = result.id;
+ await createPractise();
}
}
+const getResultTipSrc = (result = {}) => {
+ const validCount = (result.details || []).filter(
+ (arrow) => arrow.x !== -30 && arrow.y !== -30
+ ).length;
+ return `${RESULT_TIP_CDN}/${validCount < total ? "2un" : ""}finish-tip.png`;
+};
+
const onClickShare = debounce(async () => {
if (sharing.value) return;
sharing.value = true;
@@ -153,8 +184,7 @@ onMounted(async () => {
});
uni.$on("socket-inbox", onReceiveMessage);
uni.$on("share-image", onClickShare);
- const result = await createPractiseAPI(total, 3600, targetType.value);
- if (result) practiseId.value = result.id;
+ await createPractise();
});
onBeforeUnmount(() => {
@@ -164,7 +194,7 @@ onBeforeUnmount(() => {
uni.$off("socket-inbox", onReceiveMessage);
uni.$off("share-image", onClickShare);
audioManager.stopAll();
- endPractiseAPI();
+ closeMatchWebSocket({ reason: "practice-leave" });
});
@@ -211,13 +241,7 @@ onBeforeUnmount(() => {
:rowCount="9"
:onClose="onComplete"
:result="practiseResult"
- :tipSrc="`../static/${
- practiseResult.details.filter(
- (arrow) => arrow.x !== -30 && arrow.y !== -30
- ).length < total
- ? '2un'
- : ''
- }finish-tip.png`"
+ :tipSrc="getResultTipSrc(practiseResult)"
/>
diff --git a/src/pages/ranking.vue b/src/pages/ranking.vue
index 3024ae0..ade5d7b 100644
--- a/src/pages/ranking.vue
+++ b/src/pages/ranking.vue
@@ -328,8 +328,8 @@ onShow(async () => {
-
-
+
+
{
class="back-to-game"
@click="onClick"
>
-
+
-
+
返回进行中的对局
diff --git a/src/pages/team-battle/components/BattleFooter.vue b/src/pages/team-battle/components/BattleFooter.vue
index 8bc544f..4e56a27 100644
--- a/src/pages/team-battle/components/BattleFooter.vue
+++ b/src/pages/team-battle/components/BattleFooter.vue
@@ -31,7 +31,7 @@ const normalRounds = computed(() => {
-
+
+
蓝队({{ bluePoints }})
红队({{ redPoints }})
diff --git a/src/pages/team-battle/components/BattleHeader.vue b/src/pages/team-battle/components/BattleHeader.vue
index 65681f0..a6ee495 100644
--- a/src/pages/team-battle/components/BattleHeader.vue
+++ b/src/pages/team-battle/components/BattleHeader.vue
@@ -41,7 +41,7 @@ const isMember = (player = {}) => player.vip === true || player.sVip === true;
{
@impact="shakeTarget"
@complete="completeShotEffect"
/>
-
+