創建像 Skribbl.io 這樣的即時多人遊戲是一項令人興奮的挑戰,它結合了 Web 開發的各個方面。在這篇文章中,我將討論我在建立即時克隆時的實現和思考,以及如何處理基於回合和計時器系統的遊戲
如果您想查看該專案的源代碼,您可以在 Github 上找到它
技術堆疊
在深入了解細節之前,我們先簡單了解一下該專案所使用的技術堆疊:
- Node.js:用於後端伺服器。
- Socket.IO:用於即時通訊。
- Redis:用於高效率的資料處理。
- Vite:使用 React 進行快速開發。
- TypeScript:用於前端和後端的類型安全。
- React:用於建立使用者介面。
- Docker:用於容器化應用程式。
設定後端
後端由 Node.js 和 Socket.IO 提供支持,非常適合處理即時互動。以下是主要組件的快速概述:
1. 用於即時通訊的WebSockets
Socket.IO 允許伺服器和客戶端之間的無縫通訊。我們用它來處理玩家加入房間、開始遊戲、發送繪圖資料等事件。
2. 房間系統
每個遊戲都在一個唯一的房間中託管,由房間 ID 標識。玩家使用此 ID 加入房間並與同一房間中的其他人互動。該系統還處理玩家連接和斷開連接。
但是這裡我們有一個問題,如果伺服器崩潰了,我們如何確保我們的伺服器保留遊戲中的資料
這裡我們使用一個速度快的資料庫,也是與伺服器分開的主體
Redis 是此類用例的絕佳選擇。它是一個記憶體資料庫,速度很快,可以在不同的伺服器上單獨運行
我們稍後會在帖子中詳細討論這一點。
3. 事件處理
伺服器監聽並發出各種事件:
-
客戶端事件:連線、斷線、joinRoom、leaveRoom、startGame、draw、guess、changeSettings、wordSelect
-
伺服器事件:joinedRoom、playerJoined、playerLeft、gameStarted、gameEnded、drawData、guessed、turnEnded、chooseWord、wordChosen、settingsChanged、guessFail
開發前端
對於前端,我使用了 React 和 TypeScript 以及 Vite,以獲得流暢的開發體驗。
1. 建構使用者介面
使用者介麵包括用於繪圖、猜測和管理遊戲設定的元件。 React 基於元件的架構可以輕鬆建立動態且響應式的 UI。
2. 處理遊戲狀態
前端管理遊戲狀態,包括玩家得分、當前回合和繪圖資料。 TypeScript 確保資料結構定義明確且無錯誤。
3. 即時更新
使用Socket.IO,前端根據伺服器事件即時更新。例如,當玩家抽獎時,抽獎資料會發送給房間內的所有客戶端。
遊戲狀態管理
有效的遊戲狀態管理對於確保像 Skribbl.io 這樣的即時多人遊戲的流暢和愉快的體驗至關重要。以下詳細介紹如何管理遊戲狀態的各個面向:
玩家加入和離開
管理玩家加入和離開房間涉及幾個關鍵步驟:
-
加入:
-
事件發送:當玩家想要加入房間時,他們會向伺服器發送帶有房間 ID 的 joinRoom 事件。
-
驗證:伺服器驗證房間ID並檢查房間是否存在。
-
新增玩家:如果有效,則將玩家加入房間的玩家清單。然後,伺服器更新遊戲狀態並向房間中的所有用戶端發出playerJoined 事件,通知他們新玩家的到來。
-
UI 更新:在前端,新玩家的存在會反映在房間的玩家清單中,確保每個人都能看到最新的玩家名單。
-
離開:
-
事件發射:當玩家決定離開時,他們會向伺服器發送一個leaveRoom事件。
-
玩家移除:伺服器將玩家從房間的玩家清單中移除,並相應更新遊戲狀態。
-
通知:伺服器向所有剩餘的客戶端發出playerLeft事件,通知他們玩家已經離開房間。
-
UI 更新:前端透過從玩家清單中刪除玩家並在必要時調整任何正在進行的遊戲機制來反映此變更。
選詞
選擇一個單字並管理輪到誰選擇涉及多種機制:
-
目前玩家回合:
-
輪次管理:伺服器維護輪到誰選擇單字的記錄。這是由遊戲狀態管理的,其中包括指示當前玩家 ID 的屬性。
-
單字選擇提示:輪到玩家選擇單字時,他們會從伺服器收到一個chooseWord事件,提示他們選擇一個單字。
-
防止單字外洩:
-
回合限制存取:所選單字不會立即廣播給其他玩家。相反,它僅在輪到抽屜時才共享,以防止任何不公平的優勢。
-
事件發射:一旦抽屜選擇了單詞,伺服器就會向所有玩家發出一個 wordChosen 事件。此事件包括一個通知,表明該單字已被選擇並準備好猜測。
-
單字選擇通知:
-
廣播:wordChosen 事件包含一個已選取單字的通知,該通知會傳送給房間中的所有玩家。
-
前端處理:在客戶端,玩家進行更新以指示繪圖階段已經開始,他們現在可以開始猜測。
處理單字選擇的超時
處理目前玩家可能延遲單字選擇的情況:
-
自動分配:
-
超時機制:伺服器實作了一個計時器,在輪到玩家選擇單字時啟動。如果玩家沒有在規定時間內選擇單字,則會觸發逾時事件。
-
單字分配:伺服器自動從預定義清單中選擇一個單字並將其分配給玩家。這可以確保遊戲繼續進行,不會出現不必要的延遲。
-
通知:然後發出一個 wordChosen 事件,通知所有玩家單字已被指派並且繪圖階段即將開始。
繪圖資料處理
處理繪圖資料對於維持玩家之間的同步至關重要:
-
即時繪圖:
-
繪圖事件:玩家使用繪圖事件將繪圖資料傳送到伺服器。此資料包括畫筆顏色、半徑和繪製點的座標。
-
廣播:伺服器接收此資料並使用drawData事件將其廣播到房間中的所有客戶端。這確保了每個玩家的畫布都即時更新為最新的繪圖資訊。
處理玩家猜測事件
管理玩家的猜測涉及處理和驗證每個猜測:
-
猜測提交:
-
事件處理:當玩家進行猜測時,他們會向伺服器發送一個帶有猜測詞的猜測事件。
-
驗證:伺服器處理猜測,並根據正確的單字進行檢查。如果猜測正確,伺服器會更新遊戲狀態和玩家分數。
-
播出結果:
-
猜測結果:伺服器向所有玩家發出猜測事件,指示猜測是否正確。
-
UI 更新:在前端,結果向所有玩家顯示,顯示誰猜對了並更新遊戲進度。
繪畫和猜測的超時
管理時間限制是維持遊戲吸引力的關鍵:
-
抽獎時間結束:
-
時間管理:每輪都有規定的抽獎時間限制。伺服器會追蹤這個時間,並在時間到期時觸發turnEnded事件。
-
過渡:此事件標誌著抽獎階段的結束,遊戲過渡到猜測階段或下一輪。
-
所有玩家都猜到了:
-
猜測完成:如果所有玩家在時間耗盡之前猜出單詞,伺服器會提前觸發turnEnded事件。
-
遊戲流程:此事件會向所有客戶端更新猜測階段已完成並將遊戲過渡到下一個階段或回合。
這種管理遊戲狀態的方法可確保所有玩家獲得流暢、互動且公平的體驗,從而增強遊戲的整體樂趣。
結論
建構 Skribbl.io 克隆涉及即時通訊、遊戲狀態管理和使用者互動的複雜交互作用。透過這個項目,我們探索了遊戲開發的各個方面,從處理玩家連接和單字選擇到管理繪圖數據和玩家猜測。
重點
-
即時通訊:利用 Socket.IO 實現無縫和互動式遊戲,確保所有玩家保持同步。
-
狀態管理:有效處理遊戲狀態(例如玩家加入、單字選擇和繪圖資料)對於流暢的使用者體驗至關重要。實施逾時和自動分配可確保遊戲順利進行。
-
使用者體驗:保持引人入勝且反應迅速的介面可以提高玩家滿意度。對繪畫和猜測等動作的清晰回饋,加上及時的更新,可以讓玩家了解情況並投入遊戲中。
下一步
如果您有靈感進一步推進這個項目,請考慮:
-
新增功能:實作額外的遊戲模式、自訂或增強功能,讓遊戲更動態。
-
最佳化效能:探索提高效能的方法,例如最佳化繪圖資料傳輸或減少延遲。
-
增強 UI/UX:根據玩家回饋完善使用者介面和體驗,讓遊戲更有趣。
這個專案是一次令人興奮的即時遊戲開發之旅,結合了各種技術和技巧來創造有趣且引人入勝的多人遊戲體驗。我希望本文能為遊戲狀態管理提供寶貴的見解,並激勵您在遊戲開發領域進行更多探索。
請隨時在下面的評論中分享您對此項目的想法、問題或改進。快樂編碼!
以上是建構 Skribbl.io 克隆:從概念到完成的詳細內容。更多資訊請關注PHP中文網其他相關文章!