本系列文已改編成書「甚麼?網頁也可以做派對遊戲?使用 Vue 和 babylon.js 打造 3D 派對遊戲吧!」
書中不只重構了程式架構、改善了介面設計,還新增了 2 個新遊戲呦!ˋ( ° ▽、° )
新遊戲分別使用了陀螺儀與震動回饋,趕快買書來研究研究吧!ლ(╹∀╹ლ)
在此感謝深智數位的協助,歡迎大家前往購書,鱈魚感謝大家 (。・∀・)。
助教:「所以到底差在哪啊?沒圖沒真相,被你坑了都不知道。(´。_。`)」
鱈魚:「你對我是不是有甚麼很深的偏見啊 (っ °Д °;)っ,來人啊,上連結!」
既然已經可以建立房間了,那就讓我們來把遊戲大廳做出來吧!
預期會有以下內容:
但是我們還要先 route 的部份才行,首先新增頁面組件。
src\views\game-console-lobby.vue
<template>
<div class="flex">
我是 game-console-lobby
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
</script>
<style scoped lang="sass">
</style>
將頁面加到 Router 中。
src\router\router.ts
...
export enum RouteName {
...
GAME_CONSOLE = 'game-console',
GAME_CONSOLE_LOBBY = 'game-console-lobby',
}
const routes: Array<RouteRecordRaw> = [
...
{
path: `/game-console`,
name: RouteName.GAME_CONSOLE,
component: () => import('../views/game-console.vue'),
children: [
{
path: `lobby`,
name: RouteName.GAME_CONSOLE_LOBBY,
component: () => import('../views/game-console-lobby.vue')
},
]
},
...
]
...
game-console 組件中需要依照狀態執行對應邏輯,例如跳轉頁面等等,但前提是要先有狀態資料才行,所以讓我們新增 game-console.store 儲存資料。
先來設計資料型別。
/** 遊戲狀態 */
export enum GameConsoleStatus {
/** 首頁 */
HOME = 'home',
/** 大廳等待中 */
LOBBY = 'lobby',
/** 遊戲中 */
PLAYING = 'playing',
}
/** 遊戲名稱列舉 */
export enum GameName { }
/** 玩家 */
export interface Player {
clientId: string;
}
/** 更新遊戲機狀態
*
* roomId 不可變更,以外參數允許持續更新
*/
export type UpdateGameConsoleState = Partial<Omit<State, 'roomId'>>;
interface State {
status: `${GameConsoleStatus}`;
gameName?: `${GameName}`;
roomId?: string;
players: Player[];
}
完成內容。
src\stores\game-console.store.ts
...
export const useGameConsoleStore = defineStore('game-console', {
state: (): State => ({
status: 'home',
gameName: undefined,
/** 房間 ID,6 位數字 */
roomId: undefined,
players: [],
}),
actions: {
updateState(state: UpdateGameConsoleState) {
this.$patch({
...state
});
},
setRoomId(roomId: string) {
this.$patch({
roomId
});
},
}
})
接著回到 the-home 中,引用 game-console.store 讓我們儲存房間 ID。
src\views\the-home.vue
<script setup lang="ts">
...
const gameConsoleStore = useGameConsoleStore();
async function startParty() {
...
console.log(`[ startParty ] roomId : `, roomId);
gameConsoleStore.setRoomId(roomId);
router.push({
name: RouteName.GAME_CONSOLE
});
}
</script>
現在我們有 game-console 的狀態資料可以用了,所以讓我們回到 game-console 頁面組件,新增跳轉邏輯,讓房間建立完成後,遊戲機的畫面會跳轉至 game-console-lobby。
首先調整 template 內容,只要一個 router-view 即可。
src\views\game-console.vue
<template>
<router-view />
</template>
...
接著完成依據目前狀態跳轉頁面功能。
<script setup lang="ts">
import { RouteName } from '../router/router';
import { useRouter } from 'vue-router';
import { useLoading } from '../composables/use-loading';
import { useGameConsoleStore } from '../stores/game-console.store';
const loading = useLoading();
const router = useRouter();
const gameConsoleStore = useGameConsoleStore();
function init() {
// 房間 ID 不存在,跳回首頁
if (!gameConsoleStore.roomId) {
router.push({
name: RouteName.HOME
});
loading.hide();
return;
}
// 跳轉至遊戲大廳
router.push({
name: RouteName.GAME_CONSOLE_LOBBY
});
}
init();
</script>
最後在 game-console-lobby 頁面隱藏 loading。
src\views\game-console-lobby.vue
<template>
<div class="text-7xl">
我是 game-console-lobby
</div>
</template>
<script setup lang="ts">
import { useLoading } from '../composables/use-loading';
const loading = useLoading();
loading.hide();
</script>
<style scoped lang="sass">
</style>
來試試看效果。
現在會在房間建立完成後,自動降肉 game-console-lobby 頁面了!(゜▽゜*)♪
以上程式碼已同步至 GitLab,大家可以前往下載: