基於聲網互動白板實現一個多人數獨遊戲

聲網發表於2023-02-14
本文作者是聲網社群的開發者“tjss”。他基於Vue、聲網的互動白板的程式碼模板,搭建出了一個支援多人互動的數獨遊戲。本文記錄了他的實現過程,歡迎大家也可以嘗試實現自己的小遊戲或應用。本文涉及的聲網產品均支援免費註冊下載,併為每個開發者提供每月免費 10000 分鐘使用額度,歡迎大家嘗試體驗、實踐。

我基於聲網互動白板的 SDK 與 Window Manager 開發了一個場景化視窗外掛,實現了一個多人數獨遊戲。在遊戲中,每個玩家進入白板房間,都能看到數獨遊戲外掛,同時可以參與其中,與房間內的小夥伴一起完成數獨解題。

前期準備

1、註冊一個聲網賬號,並實名認證,以便在後臺建立專案,獲取開發時會用到的 Appid 和 Token

2、瞭解 Vue 開發的基礎知識。

3、瞭解聲網互動白板產品,一些基本的介面和功能,看官方文件就足夠了。

4、搭建開發環境:

  • NodeJs 版本 16.0.0
  • @Vue/cli 4.5.1
  • VSCode 程式碼開發工具

開啟和配置互動白板服務

首先我們需要一個實名認證的聲網賬號,進入控制檯(console.agora.io),在聲網控制檯開啟互動白板服務。這裡需要注意的是互動白板是作為服務而顯示的,而控制檯中只是顯示專案列表,並沒有直接顯示服務。

圖片

這時候我們就先建立一個專案,然後點選“配置”進入到專案詳情中,在裡面的頁面就可以看到服務內容了。

圖片

這時候找到互動白板服務,點選開啟就行。因為我的已經開啟了,所以顯示的是配置按鈕。

圖片

使用官網提供的程式碼模板

場景化視窗外掛目前我們不需要從零開始建立的,聲網提供了一個程式碼模板,基於此模板我們可以很輕鬆就能實現一個在互動白板上使用的外掛。

模板地址:https://github.com/netless-io...

當搭建好開發環境後,便可以下載模板程式碼了,透過 Git 或者下載 Zip 都行。

需要注意 README.md 中的開發環境配置:

1、在 .env 檔案裡配置白板房間 UUID 和 Token請將本目錄下的 .env.example 檔案複製一份,重新命名為 .env 或 .env.local 後,在裡面填寫必須的白板配置資訊。你可以在聲網互動白板官方的 Netless Workshop 申請專用的白板配置。

2、執行 npm install 安裝依賴

3、執行 npm start 進行本地開發

專案結構

筆者是基於 Vue 版本的外掛模板進行開發的,直接開啟專案,修改 src 裡的內容即可,基本上和 Vue 開發一致。如果是透過 Git 命令拉取的程式碼,需要切換分支為 Vue 分支。

圖片

  • 專案結構如下:

圖片

  • playground 目錄是基本不用修改的,我們實現的外掛是在 src 目錄中完成的。
  • index.ts 檔案是我們外掛的一些資料設定,比如外掛名稱。其他邏輯基本不用修改。
onst Sudoku: NetlessApp = {
  kind: "Sudoku",
  setup(context) {
    const box = context.getBox();
    box.mountStyles(styles);
    const $content = document.createElement("div");
    $content.className = "app-counter";
    box.mountContent($content);
    const app = createApp(App).provide("context", context);
    app.mount($content);
    context.emitter.on("destroy", () => {
      app.unmount();
    });
  },
};
export default Sudoku;

數獨遊戲規則

數獨網格由 9x9 個空格組成。玩家只能使用數字 1 到 9,每個 3×3 宮只能包含數字 1 到 9,每一列只能包含數字 1 到 9,每一行只能包含數字 1 到 9,每個 3×3 宮、每一列或每一行中的每個數字只能使用一次。當所有數獨網格都填入正確的數字時,遊戲結束。(摘自網上)

資料同步核心思路

1、透過互動白板SDK提供的 createStorage 方法,初始化一個數獨棋盤,並把資料儲存起來,同時需要更新自己的 chessBoard。

const chessBoard = ref();
const context = inject<AppContext>("context");
const storage = context.createStorage("chessBoard", { chessBoard: ChessBoard.init() });
chessBoard.value = deepCopy(storage.state.chessBoard)

2、在 Vue 介面的 onMounted 回撥函式中新增儲存值的更新監聽,這樣玩家在填格子的時候廣播了最新的格子資料,其他玩家就能收到更新的通知,然後重新渲染介面。

onMounted(() => {
  initAppData()
  storage.addStateChangedListener((diff) => {
    chessBoard.value = deepCopy(diff.chessBoard?.newValue)
    if (finish(chessBoard.value.gridItems)) {
      statistics(chessBoard.value.gridItems)
      finishTag.value = true
    }
  })
});

3、填格子的時候,透過 SDK 的 setState 方法去更新數獨棋盤的資料。

if (e.data && e.data > 0) {
    grid.number = parseInt(e.data)
    grid.userId = uid.value
    grid.color = rgb
  } else {
    grid.number = 0
    grid.userId = ''
    grid.color = new Rgb(233, 233, 233)
  }
  storage.setState({ chessBoard: chessBoard.value })

數獨遊戲介面

筆者是優先實現這個互動遊戲的核心功能,所以設計出的遊戲介面比較簡陋。

圖片

數獨的資料結構

export class ChessBoard {
    gridItems: GridItem[][]
}

因為需要統計遊戲結束後,各個玩家填寫的個數,所以在更新格子數值的時候也記錄一下是哪一位玩家填寫了。default 欄位表示該格子是自動生成的,不需要玩家填寫了。

export class GridItem {
    number: number
    color: Rgb
    userId: string
    default: boolean
}

執行專案

點選工具欄最下方的按鈕,可以找到我們實現的外掛icon,然後點選即可開啟。

圖片

開啟外掛後,會初始化建立一個數獨題目,並且透過 createStorage 方法儲存起來,所有進入房間的玩家都能拿到這個資料,後續數獨的更新都會同步給玩家去修改。因為這個專案重點是學習一下外掛開發與資料同步,所以遊戲介面以及內容這些做的比較簡單。

圖片

接下來就要開啟多個網頁並且輸入 localhost:3000 進入我們的互動白板房間了,因為模板的uid是隨機生成的,也就表示有不同的玩家進入了。

圖片

別的玩家填寫後,其他玩家是不能再填這個格子的,最後遊戲結束的時候,會統計各個玩家所填對的數字並展示。

圖片

遊戲結束

圖片

總結

透過官方提供的場景化外掛模板,我們很容易實現一些好玩的互動場景的功能。在這個簡單的專案中,由於時間倉促,還沒來得及最佳化得更好,後續有時間的時候筆者再打磨一下。比如不同玩家填寫的數字以不同的顏色區分,增加限時機制等等。感興趣的朋友一起來開發一些好玩的實時互動功能吧~

現註冊聲網賬號下載 SDK,可獲得每月免費 10000 分鐘使用額度。如在開發過程中遇到疑問,可在聲網開發者社群與官方工程師交流。

相關文章