iT邦幫忙

2022 iThome 鐵人賽

DAY 12
1
Modern Web

派對動物嗨起來!系列 第 12

D12 - 歡迎光臨遊戲大廳:使用 Vue Router 切換頁面

  • 分享至 

  • xImage
  •  

本系列文已改編成書「甚麼?網頁也可以做派對遊戲?使用 Vue 和 babylon.js 打造 3D 派對遊戲吧!」

書中不只重構了程式架構、改善了介面設計,還新增了 2 個新遊戲呦!ˋ( ° ▽、° )

新遊戲分別使用了陀螺儀與震動回饋,趕快買書來研究研究吧!ლ(╹∀╹ლ)

在此感謝深智數位的協助,歡迎大家前往購書,鱈魚感謝大家 (。・∀・)。

助教:「所以到底差在哪啊?沒圖沒真相,被你坑了都不知道。(´。_。`)」

鱈魚:「你對我是不是有甚麼很深的偏見啊 (っ °Д °;)っ,來人啊,上連結!」

Yes


既然已經可以建立房間了,那就讓我們來把遊戲大廳做出來吧!

預期會有以下內容:

  • 房間 ID
  • 主選單:開始遊戲、結束派對
  • 遊戲選擇清單
  • 所有玩家頭像

但是我們還要先 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>

來試試看效果。

ezgif-5-ef95437760.gif

現在會在房間建立完成後,自動降肉 game-console-lobby 頁面了!(゜▽゜*)♪

總結

  • 建立 game-console.store 儲存遊戲機資料
  • 成功於房間建立後,跳轉至 game-console-lobby 頁面

以上程式碼已同步至 GitLab,大家可以前往下載:

GitLab - D12


上一篇
D11 - 開房間!開派對!♪( ◜ω◝و(و
下一篇
D13 - 來布置一下吧
系列文
派對動物嗨起來!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言