本文作者是聲網社群的開發者“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 分鐘使用額度。如在開發過程中遇到疑問,可在聲網開發者社群與官方工程師交流。