128 lines
4.1 KiB
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>
|