完成加入,退出房间
This commit is contained in:
@@ -6,7 +6,7 @@ try {
|
|||||||
|
|
||||||
switch (envVersion) {
|
switch (envVersion) {
|
||||||
case "develop": // 开发版
|
case "develop": // 开发版
|
||||||
BASE_URL = "https://apitest.shelingxingqiu.com/api/shoot";
|
BASE_URL = "http://192.168.1.242:8000/api/shoot";
|
||||||
break;
|
break;
|
||||||
case "trial": // 体验版
|
case "trial": // 体验版
|
||||||
BASE_URL = "https://apitest.shelingxingqiu.com/api/shoot";
|
BASE_URL = "https://apitest.shelingxingqiu.com/api/shoot";
|
||||||
@@ -444,3 +444,7 @@ export const getPractiseDataAPI = async () => {
|
|||||||
export const getBattleDataAPI = async () => {
|
export const getBattleDataAPI = async () => {
|
||||||
return request("GET", "/user/fight/statistics");
|
return request("GET", "/user/fight/statistics");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const chooseTeamAPI = async (number, group) => {
|
||||||
|
return request("POST", "/user/room/group", { number, group });
|
||||||
|
};
|
||||||
|
|||||||
@@ -23,10 +23,11 @@ const createRoom = async () => {
|
|||||||
}
|
}
|
||||||
if (loading.value === true) return;
|
if (loading.value === true) return;
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const result = await createRoomAPI(
|
let size = 2;
|
||||||
battleMode.value,
|
if (battleMode.value === 2) size = 10;
|
||||||
battleMode.value === 1 ? 2 : 10
|
if (battleMode.value === 3) size = 4;
|
||||||
);
|
if (battleMode.value === 4) size = 6;
|
||||||
|
const result = await createRoomAPI(battleMode.value === 2 ? 2 : 1, size);
|
||||||
if (result.number) roomNumber.value = result.number;
|
if (result.number) roomNumber.value = result.number;
|
||||||
step.value = 2;
|
step.value = 2;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const barColor = ref("linear-gradient( 180deg, #FFA0A0 0%, #FF6060 100%)");
|
const barColor = ref("linear-gradient( 180deg, #FFA0A0 0%, #FF6060 100%)");
|
||||||
const remain = ref(10);
|
const remain = ref(15);
|
||||||
const timer = ref(null);
|
const timer = ref(null);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
|||||||
@@ -9,17 +9,24 @@ const props = defineProps({
|
|||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
currentShooterId: {
|
||||||
|
type: Number,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
youTurn: {
|
youTurn: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const players = ref(props.team);
|
const players = ref(props.team);
|
||||||
|
const youTurn = ref(false);
|
||||||
watch(
|
watch(
|
||||||
() => props.youTurn,
|
() => props.currentShooterId,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
players.value = props.team;
|
const exit = props.team.some((p) => p.id === newVal);
|
||||||
}
|
youTurn.value = !!exit;
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ export const MESSAGETYPES = {
|
|||||||
PaySuccess: 3793388244,
|
PaySuccess: 3793388244,
|
||||||
RankUpdate: 1121669910,
|
RankUpdate: 1121669910,
|
||||||
LvlUpdate: 3958625354,
|
LvlUpdate: 3958625354,
|
||||||
|
TeamUpdate: 4168086616,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const topThreeColors = ["#FFD947", "#D2D2D2", "#FFA515"];
|
export const topThreeColors = ["#FFD947", "#D2D2D2", "#FFA515"];
|
||||||
|
|||||||
@@ -7,7 +7,13 @@ import Guide from "@/components/Guide.vue";
|
|||||||
import SButton from "@/components/SButton.vue";
|
import SButton from "@/components/SButton.vue";
|
||||||
import SModal from "@/components/SModal.vue";
|
import SModal from "@/components/SModal.vue";
|
||||||
import Avatar from "@/components/Avatar.vue";
|
import Avatar from "@/components/Avatar.vue";
|
||||||
import { getRoomAPI, destroyRoomAPI, exitRoomAPI, startRoomAPI } from "@/apis";
|
import {
|
||||||
|
getRoomAPI,
|
||||||
|
destroyRoomAPI,
|
||||||
|
exitRoomAPI,
|
||||||
|
startRoomAPI,
|
||||||
|
chooseTeamAPI,
|
||||||
|
} from "@/apis";
|
||||||
import { MESSAGETYPES } from "@/constants";
|
import { MESSAGETYPES } from "@/constants";
|
||||||
import useStore from "@/store";
|
import useStore from "@/store";
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
@@ -17,12 +23,9 @@ const room = ref({});
|
|||||||
const roomNumber = ref("");
|
const roomNumber = ref("");
|
||||||
const owner = ref({});
|
const owner = ref({});
|
||||||
const opponent = ref({});
|
const opponent = ref({});
|
||||||
const players = ref([
|
const players = ref([]);
|
||||||
{ name: "player1", team: 1 },
|
const blueTeam = ref([]);
|
||||||
{ name: "player2", team: 0 },
|
const redTeam = ref([]);
|
||||||
{ name: "player3", team: 2 },
|
|
||||||
{ name: "player4", team: 1 },
|
|
||||||
]);
|
|
||||||
|
|
||||||
const showModal = ref(false);
|
const showModal = ref(false);
|
||||||
const battleType = ref(0);
|
const battleType = ref(0);
|
||||||
@@ -44,7 +47,7 @@ async function refreshRoomData() {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
if (result.battleType === 1) {
|
if (result.battleType === 1 && result.count === 1) {
|
||||||
if (user.value.id !== owner.value.id) {
|
if (user.value.id !== owner.value.id) {
|
||||||
opponent.value = {
|
opponent.value = {
|
||||||
id: user.value.id,
|
id: user.value.id,
|
||||||
@@ -77,6 +80,9 @@ async function refreshRoomData() {
|
|||||||
result.members.forEach((m, index) => {
|
result.members.forEach((m, index) => {
|
||||||
if (ownerIndex !== index) players.value.push(m.userInfo);
|
if (ownerIndex !== index) players.value.push(m.userInfo);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
players.value = new Array(result.count).fill({});
|
||||||
|
refreshMembers(result.members);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +90,23 @@ const startGame = async () => {
|
|||||||
const result = await startRoomAPI(room.value.number);
|
const result = await startRoomAPI(room.value.number);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const refreshMembers = (members) => {
|
||||||
|
blueTeam.value = [];
|
||||||
|
redTeam.value = [];
|
||||||
|
members.forEach((m, index) => {
|
||||||
|
players.value[index] = { ...m.userInfo, groupType: m.groupType };
|
||||||
|
if (m.groupType === 1) {
|
||||||
|
blueTeam.value.push({ ...m.userInfo, groupType: 1 });
|
||||||
|
} else if (m.groupType === 0) {
|
||||||
|
redTeam.value.push({ ...m.userInfo, groupType: 0 });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (let i = 0; i < room.value.count / 2; i++) {
|
||||||
|
if (!blueTeam.value[i]) blueTeam.value[i] = {};
|
||||||
|
if (!redTeam.value[i]) redTeam.value[i] = {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
async function onReceiveMessage(messages = []) {
|
async function onReceiveMessage(messages = []) {
|
||||||
messages.forEach((msg) => {
|
messages.forEach((msg) => {
|
||||||
if (msg.roomNumber === roomNumber.value) {
|
if (msg.roomNumber === roomNumber.value) {
|
||||||
@@ -134,6 +157,14 @@ async function onReceiveMessage(messages = []) {
|
|||||||
if (battleType.value === 2) {
|
if (battleType.value === 2) {
|
||||||
players.value = players.value.filter((p) => p.id !== msg.userId);
|
players.value = players.value.filter((p) => p.id !== msg.userId);
|
||||||
}
|
}
|
||||||
|
if (msg.room && msg.room.members) {
|
||||||
|
refreshMembers(msg.room.members);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (msg.constructor === MESSAGETYPES.TeamUpdate) {
|
||||||
|
if (msg.room && msg.room.members) {
|
||||||
|
refreshMembers(msg.room.members);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (msg.constructor === MESSAGETYPES.RoomDestroy) {
|
if (msg.constructor === MESSAGETYPES.RoomDestroy) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
@@ -169,6 +200,17 @@ async function onReceiveMessage(messages = []) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const chooseTeam = async (team) => {
|
||||||
|
if (team !== 2) {
|
||||||
|
const notInTeam = room.value.members.some(
|
||||||
|
(m) => m.userInfo.id === user.value.id && m.groupType === 2
|
||||||
|
);
|
||||||
|
if (!notInTeam) return;
|
||||||
|
}
|
||||||
|
const result = await chooseTeamAPI(roomNumber.value, team);
|
||||||
|
refreshMembers(result.members);
|
||||||
|
};
|
||||||
|
|
||||||
const destroyRoom = async () => {
|
const destroyRoom = async () => {
|
||||||
if (roomNumber.value) await destroyRoomAPI(roomNumber.value);
|
if (roomNumber.value) await destroyRoomAPI(roomNumber.value);
|
||||||
};
|
};
|
||||||
@@ -237,7 +279,7 @@ onHide(() => {});
|
|||||||
<view @click="setClipboardData">复制房间号</view>
|
<view @click="setClipboardData">复制房间号</view>
|
||||||
</view>
|
</view>
|
||||||
</Guide>
|
</Guide>
|
||||||
<view v-if="battleType === 1" class="team-mode">
|
<view v-if="battleType === 1 && room.count === 2" class="team-mode">
|
||||||
<image
|
<image
|
||||||
src="https://static.shelingxingqiu.com/attachment/2025-08-05/dbua9nuf5fyeph7cxi.png"
|
src="https://static.shelingxingqiu.com/attachment/2025-08-05/dbua9nuf5fyeph7cxi.png"
|
||||||
mode="widthFix"
|
mode="widthFix"
|
||||||
@@ -270,6 +312,7 @@ onHide(() => {});
|
|||||||
:total="room.count || 10"
|
:total="room.count || 10"
|
||||||
:players="players"
|
:players="players"
|
||||||
/>
|
/>
|
||||||
|
<block v-if="battleType === 1 && room.count >= 4">
|
||||||
<view class="all-players">
|
<view class="all-players">
|
||||||
<image
|
<image
|
||||||
src="https://static.shelingxingqiu.com/attachment/2025-08-13/dc0x1p59iab6cvbhqc.png"
|
src="https://static.shelingxingqiu.com/attachment/2025-08-13/dc0x1p59iab6cvbhqc.png"
|
||||||
@@ -278,36 +321,57 @@ onHide(() => {});
|
|||||||
<image src="../static/title-2v2.png" mode="widthFix" />
|
<image src="../static/title-2v2.png" mode="widthFix" />
|
||||||
<view>
|
<view>
|
||||||
<view v-for="(item, index) in players" :key="index">
|
<view v-for="(item, index) in players" :key="index">
|
||||||
<Avatar :src="item.avatar" :size="36" />
|
<Avatar v-if="item.id" :src="item.avatar" :size="36" />
|
||||||
<text v-if="index === 0">创建者</text>
|
<text v-if="owner.id === item.id">创建者</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="choose-side">
|
<view class="choose-side">
|
||||||
<view>
|
<view>
|
||||||
<view v-for="i in 3" :key="i" class="choose-side-left-item">
|
<view
|
||||||
<button hover-class="none">
|
v-for="(item, index) in blueTeam"
|
||||||
|
:key="index"
|
||||||
|
class="choose-side-left-item"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
hover-class="none"
|
||||||
|
v-if="item.id === user.id"
|
||||||
|
@click="chooseTeam(2)"
|
||||||
|
>
|
||||||
<image src="../static/close-grey.png" mode="widthFix" />
|
<image src="../static/close-grey.png" mode="widthFix" />
|
||||||
</button>
|
</button>
|
||||||
<text class="truncate">23232323232</text>
|
<text class="truncate">{{ item.name || "我要加入" }}</text>
|
||||||
<Avatar :size="36" />
|
<Avatar v-if="item.id" :src="item.avatar" :size="36" />
|
||||||
</view>
|
<button v-else hover-class="none" @click="chooseTeam(1)">
|
||||||
</view>
|
|
||||||
<view>
|
|
||||||
<view v-for="i in 3" :key="i" class="choose-side-right-item">
|
|
||||||
<button hover-class="none">
|
|
||||||
<image src="../static/add-grey.png" mode="widthFix" />
|
<image src="../static/add-grey.png" mode="widthFix" />
|
||||||
</button>
|
</button>
|
||||||
<text class="truncate">22222</text>
|
</view>
|
||||||
<button hover-class="none">
|
</view>
|
||||||
|
<view>
|
||||||
|
<view
|
||||||
|
v-for="(item, index) in redTeam"
|
||||||
|
:key="index"
|
||||||
|
class="choose-side-right-item"
|
||||||
|
>
|
||||||
|
<Avatar v-if="item.id" :src="item.avatar" :size="36" />
|
||||||
|
<button v-else hover-class="none" @click="chooseTeam(0)">
|
||||||
|
<image src="../static/add-grey.png" mode="widthFix" />
|
||||||
|
</button>
|
||||||
|
<text class="truncate">{{ item.name || "我要加入" }}</text>
|
||||||
|
<button
|
||||||
|
hover-class="none"
|
||||||
|
v-if="item.id === user.id"
|
||||||
|
@click="chooseTeam(2)"
|
||||||
|
>
|
||||||
<image src="../static/close-grey.png" mode="widthFix" />
|
<image src="../static/close-grey.png" mode="widthFix" />
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
</block>
|
||||||
<view>
|
<view>
|
||||||
<SButton
|
<SButton
|
||||||
v-if="user.id === owner.id && battleType === 1"
|
v-if="user.id === owner.id && battleType === 1 && room.count === 2"
|
||||||
:disabled="!opponent.id"
|
:disabled="!opponent.id"
|
||||||
:onClick="startGame"
|
:onClick="startGame"
|
||||||
>进入对战</SButton
|
>进入对战</SButton
|
||||||
@@ -318,6 +382,14 @@ onHide(() => {});
|
|||||||
:onClick="startGame"
|
:onClick="startGame"
|
||||||
>进入大乱斗</SButton
|
>进入大乱斗</SButton
|
||||||
>
|
>
|
||||||
|
<SButton
|
||||||
|
v-if="user.id === owner.id && battleType === 1 && room.count >= 4"
|
||||||
|
:disabled="
|
||||||
|
players.some((p) => p.groupType === undefined || p.groupType === 2)
|
||||||
|
"
|
||||||
|
:onClick="startGame"
|
||||||
|
>开启对局</SButton
|
||||||
|
>
|
||||||
<SButton v-if="user.id !== owner.id" disabled>等待房主开启对战</SButton>
|
<SButton v-if="user.id !== owner.id" disabled>等待房主开启对战</SButton>
|
||||||
<text class="tips">创建者点击下一步,所有人即可进入游戏。</text>
|
<text class="tips">创建者点击下一步,所有人即可进入游戏。</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -559,6 +631,7 @@ onHide(() => {});
|
|||||||
.choose-side-right-item > text {
|
.choose-side-right-item > text {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
max-width: 100px;
|
max-width: 100px;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
.choose-side-left-item > button:first-child,
|
.choose-side-left-item > button:first-child,
|
||||||
.choose-side-right-item > button:last-child {
|
.choose-side-right-item > button:last-child {
|
||||||
|
|||||||
@@ -315,14 +315,9 @@ onHide(() => {
|
|||||||
:team="blueTeam"
|
:team="blueTeam"
|
||||||
:isRed="false"
|
:isRed="false"
|
||||||
:currentShooterId="currentShooterId"
|
:currentShooterId="currentShooterId"
|
||||||
:youTurn="true"
|
|
||||||
/>
|
/>
|
||||||
<ShootProgress2 :tips="tips" :currentRound="'round' + currentRound" />
|
<ShootProgress2 :tips="tips" :currentRound="'round' + currentRound" />
|
||||||
<TeamAvatars
|
<TeamAvatars :team="redTeam" :currentShooterId="currentShooterId" />
|
||||||
:team="redTeam"
|
|
||||||
:currentShooterId="currentShooterId"
|
|
||||||
:youTurn="true"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
<BowTarget
|
<BowTarget
|
||||||
v-if="start"
|
v-if="start"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ function createWebSocket(token, onMessage) {
|
|||||||
|
|
||||||
switch (envVersion) {
|
switch (envVersion) {
|
||||||
case "develop": // 开发版
|
case "develop": // 开发版
|
||||||
url = "wss://apitest.shelingxingqiu.com/socket";
|
url = "ws://192.168.1.242:8000/socket";
|
||||||
break;
|
break;
|
||||||
case "trial": // 体验版
|
case "trial": // 体验版
|
||||||
url = "wss://apitest.shelingxingqiu.com/socket";
|
url = "wss://apitest.shelingxingqiu.com/socket";
|
||||||
|
|||||||
Reference in New Issue
Block a user