ColyseusJS 輕量級多人遊戲伺服器開發框架 - 中文手冊(上)

為少發表於2021-05-08

快速上手多人遊戲伺服器開發。後續會基於 Google Agones,更新相關 K8S 運維、大規模快速擴充套件專用遊戲伺服器的文章。擁抱☁️原生? Cloud-Native!

快速開始

在開始之前,讓我們確保在您的本地機器上安裝了必要的系統需求。

系統必需

建立一個 barebones(裸) Colyseus server

使用 npm init colyseus-app 命令生成 barebones(裸) Colyseus server。您可以選擇 TypeScript(推薦),JavaScriptHaxe 作為伺服器的選擇語言。

npm init colyseus-app ./my-colyseus-app

從官方的例子來看

或者,您可以通過克隆示例專案並在本地執行它來檢視一些實際示例。

git clone https://github.com/colyseus/colyseus-examples.git
cd colyseus-examples
npm install

要在本地執行伺服器,請執行 npm start,然後開啟 http://localhost:2567 檢視每個示例。

Colyseus 工作原理概述

Presentation: Overview of how Colyseus works

JavaScript/TypeScript SDK

JavaScript/TypeScript SDK 與大多數平臺相容:

用法

在專案中包括 JavaScript SDK

如果你正在使用一個構建工具(webpackrollup或類似的),這是首選的方法。

npm install --save colyseus.js

如果你不使用構建工具,建議從 GitHub Releases 下載。

<script src="colyseus.js"></script>

或者,您可以使用 unpkg 直接包括分發檔案。確保用與您的伺服器相容的版本來替換其中的 @x.x.x 部分。

<script src="https://unpkg.com/colyseus.js@^0.14.0/dist/colyseus.js"></script>

連線到伺服器:

import * as Colyseus from "colyseus.js"; // 如果通過 <script> 標記包含,則不需要。

var client = new Colyseus.Client('ws://localhost:2567');

加入一個 room(房間):

client.joinOrCreate("room_name").then(room => {
    console.log(room.sessionId, "joined", room.name);
}).catch(e => {
    console.log("JOIN ERROR", e);
});

Room 事件

Room state(狀態) 已經被更新:

room.onStateChange((state) => {
  console.log(room.name, "has new state:", state);
});

從伺服器廣播或直接廣播到此客戶端的訊息:

room.onMessage("message_type", (message) => {
  console.log(client.id, "received on", room.name, message);
});

發生伺服器錯誤:

room.onError((code, message) => {
  console.log(client.id, "couldn't join", room.name);
});

client 離開 room

room.onLeave((code) => {
  console.log(client.id, "left", room.name);
});

Cocos Creator 3.0

  • 從 GitHub 下載最新的 colyseus-js-client.zip 版本
  • 解壓 colyseus-js-client.zip 檔案。
  • colyseus.jscolyseus.d.ts 檔案移到 Cocos Creator 專案的 scripts 資料夾中。
  • 單擊 Assets 皮膚中的 colyseus.js 檔案,並啟用 "Import As Plugin"(見下圖)
  • TypeScript: 需要使用 import Colyseus from "./colyseus.js";
  • JavaScript: 需要使用 const Colyseus = require("./colyseus.js");

概述

Colyseus 目前有客戶端 SDK,可用於以下平臺:

需要另一個平臺的客戶端?在discussion board分享你的興趣吧!

例項化 Colyseus 客戶端

Client 例項用於執行配對呼叫,然後連線到一個或多個房間。

此時沒有實際的伺服器端連線。

import Colyseus from "colyseus.js";
// ...

let client = new Colyseus.Client("ws://localhost:2567");

方法

joinOrCreate (roomName: string, options: any)

通過提供的 roomNameoptions 加入現有房間或建立新房間。

此方法將忽略鎖定的房間或私人房間。

try {
  const room = await client.joinOrCreate("battle", {/* options */});
  console.log("joined successfully", room);

} catch (e) {
  console.error("join error", e);
}

create (roomName: string, options: any)

通過提供的 roomNameoptions 建立新房間。

try {
  const room = await client.create("battle", {/* options */});
  console.log("joined successfully", room);

} catch (e) {
  console.error("join error", e);
}

join (roomName: string, options: any)

通過提供的 roomNameoptions 連線一個現有的房間。

此方法將忽略鎖定的房間或私人房間。

try {
  const room = await client.join("battle", {/* options */});
  console.log("joined successfully", room);

} catch (e) {
  console.error("join error", e);
}

joinById (roomId: string, options: any)

通過 roomId 加入現有房間。私人房間可以通過 id 連線。

try {
  const room = await client.joinById("KRYAKzRo2", {/* options */});
  console.log("joined successfully", room);

} catch (e) {
  console.error("join error", e);
}

使用 getAvailableRooms() 檢索可加入的 roomId 列表。

reconnect (roomId: string, sessionId: string)

將客戶端重新連線到他以前連線的房間。

必須與伺服器端的 allowReconnection() 一起使用。

try {
  const room = await client.reconnect("wNHTX5qik", "SkNaHTazQ");
  console.log("joined successfully", room);

} catch (e) {
  console.error("join error", e);
}

getAvailableRooms (roomName?: string)

列出要連線的所有可用房間。鎖好的房間和私人房間不會被列出。roomName 是可選的。

client.getAvailableRooms("battle").then(rooms => {
  rooms.forEach((room) => {
    console.log(room.roomId);
    console.log(room.clients);
    console.log(room.maxClients);
    console.log(room.metadata);
  });
}).catch(e => {
  console.error(e);
});

consumeSeatReservation (reservation)

通過預訂座位加入一個房間。

"高階用法":
請參閱Match-maker API以瞭解如何檢索座位預訂資料。

try {
  const room = await client.consumeSeatReservation(reservation);
  console.log("joined successfully", room);

} catch (e) {
  console.error("join error", e);
}

Room API (Client-side)

屬性

state: any

當前房間的狀態。此變數始終與伺服器端的最新 state 同步。要偵聽整個狀態的更新,請參閱 onStateChange 事件。

您可以將 callbacks 附加到您 state 中的特定結構。參閱 schema callbacks

sessionId: string

當前連線的客戶端的唯一識別符號。此屬性與伺服器端的 client.sessionId 匹配。

id: string

房間的唯一標識。您可以與其他客戶端共享此 id,以便允許他們直接連線到此房間。

// get `roomId` from the query string
let roomId = location.href.match(/roomId=([a-zA-Z0-9\-_]+)/)[1];

// joining a room by its id
client.joinById(roomId).then(room => {
  // ...
});

name: string

room handler 的名稱。例如:"battle"

方法

send (type, message)

room handler 傳送一種型別的訊息。訊息是用 MsgPack 編碼的,可以儲存任何 JSON-seriazeable(JSON可序列化)的資料結構。

//
// sending message with string type
//
room.send("move", { direction: "left"});

//
// sending message with number type
//
room.send(0, { direction: "left"});

從伺服器端使用 Room#onMessage() 讀取訊息。

leave ()

與房間斷開連線。

room.leave();

使用 Room#onLeave() 處理與伺服器端的斷開連線。

removeAllListeners()

移除 onMessageonStateChangeonLeaveonError 監聽器。

如果您使用的是 Fossil Delta 序列化程式,還將刪除所有 .listen() 呼叫。。

事件

onStateChange

檢視 State Handling » Schema » Client-side 部分了解更多詳細資訊。

此事件在伺服器更新其狀態時觸發。

room.onStateChange.once((state) => {
  console.log("this is the first room state!", state);
});

room.onStateChange((state) => {
  console.log("the room state has been updated:", state);
});

onMessage

當伺服器直接向客戶端或通過廣播傳送訊息時,會觸發此事件。

room.onMessage("powerup", (message) => {
  console.log("message received from server");
  console.log(message);
});

要將訊息從伺服器直接傳送到客戶端,您需要使用 client.send()room.broadcast()

onLeave

當客戶端離開房間時觸發此事件。

可能出現的 code

room.onLeave((code) => {
  console.log("client left the room");
});

onError

room handler 中發生某些錯誤時,將觸發此事件。

room.onError((code, message) => {
  console.log("oops, error ocurred:");
  console.log(message);
});

Refs

中文手冊同步更新在:

我是為少
微信:uuhells123
公眾號:黑客下午茶
加我微信(互相學習交流),關注公眾號(獲取更多學習資料~)

相關文章