kos/web/src/views/pk/PkIndexView.vue

128 lines
4.1 KiB
Vue

<template>
<PlayGround v-if="$store.state.pk.status === 'playing'" />
<MatchGround v-else-if="$store.state.pk.status === 'matching'" />
<ResultBoard v-if="$store.state.pk.loser !== 'none'" />
</template>
<script>
import PlayGround from "../../components/PlayGround.vue";
import MatchGround from "../../components/MatchGround.vue";
import ResultBoard from "../../components/ResultBoard.vue";
// onMounted 用于组件被挂载时, onUnmounted 用于组件被解除挂载时
import { onMounted, onUnmounted } from "vue";
// 取出全局变量
import { useStore } from "vuex";
export default {
components: {
PlayGround,
MatchGround,
ResultBoard
},
// 创建前后端连接:当当前页面组件被加载时,建立连接,故使用 onMounted 函数
setup() {
const store = useStore();
// 定义后端连接的 url, 使用 ws 协议
const socketUrl = `ws://127.0.0.1:3000/websocket/${store.state.user.token}/`;
let socket = null;
// 当前组件被挂载的时候,需要创建后端连接,并且需要将连接信息存储到 store 全局变量里
onMounted(() => {
// 定义默认匹配页面对手信息(匹配等待过程中使用)
store.commit("updateOpponent", {
username: "等待对手",
photo: "https://typoraflykhan.oss-cn-beijing.aliyuncs.com/202302251825860.png",
})
store.commit("updateLoser", "none");
// 新建 WebSocket
socket = new WebSocket(socketUrl);
store.commit("updateSocket", socket);
// 调用 socket 函数: onopen 对应后端的 WebSocketServer 的 onOpen 方法
socket.onopen = () => {
console.log("frontend: connected!");
// 将 socket 存到全局变量里面
store.commit("updateSocket", socket);
}
// 从后端传过来的数据信息
socket.onmessage = (msg) => {
const data = JSON.parse(msg.data);
// console.log(data);
// data.event 在后端定义
if (data.event === "start-matching") {
// 匹配成功,更新对手信息
store.commit("updateOpponent", {
username: data.opponent_username,
photo: data.opponent_photo,
})
// 匹配成功,延迟两秒后:更改匹配状态 matching -> playing
setTimeout(() => {
store.commit("updateStatus", "playing");
}, 200);
// 匹配成功,从后端更新地图
store.commit("updateGameMap", data.game_data);
console.log(data.game_data);
}
else if (data.event === "move") {
// console.log(data);
// 调取 store 中存入的地图全局信息
const game = store.state.pk.game_object;
// 从地图全局信息中解构出 GameMap.js 中定义的 snakes
const [snake0, snake1] = game.snakes;
// 设置两条蛇的移动:后端 sendMove 中的参数
snake0.set_direction(data.a_direction);
snake1.set_direction(data.b_direction);
}
else if (data.event === "result") {
console.log(data);
const game = store.state.pk.game_object;
const [snake0, snake1] = game.snakes;
// 修改最后一步(检测到碰撞后)蛇的眼睛方向
snake0.eye_direction = data.a_eyes_finally_direction;
snake1.eye_direction = data.b_eyes_finally_direction;
// 更新 loser 信息,存储到全局 store 中
store.commit("updateLoser",data.loser);
// 更新 loser 的 snake 对象 status 状态
if (data.loser === "all" || data.loser === "A") {
snake0.status = "die";
}
if (data.loser === "all" || data.loser === "B") {
snake1.status = "die";
}
}
}
socket.onclose = () => {
console.log("frontend: disconnected");
}
});
// 离开 pk 页面时,调用 onUnmounted函数
onUnmounted(() => {
// 断开连接
socket.close();
// 离开 pk 页面时,将匹配状态改回 matching
store.commit("updateStatus", "matching");
});
}
};
</script>
<style scoped></style>