Skip to content

从 0.13 版本迁移至 0.14 版本

作为 colyseus/schema#75 的结果,Colyseus 0.14 版本对 MapSchema 的使用以及客户端的 schema 回调进行了一些重大修改, 这是因为 Schema 编码器和解码器都进行了重做.

新功能 @filterChildren(), 以及更好的 @filter() 支持! 点此阅读更多有关筛选器工作原理的内容.

升级服务器:

npm install colyseus@^0.14.0 --save

升级客户端:

npm install colyseus.js@^0.14.0 --save

若您使用的是 Unity 或其他客户端, 请在 GitHub 上查看相应资源库. 如果您有任何问题, 欢迎在 Discord 上进行询问

使用 .assign({}) 替代 constructor()

如果您用客户端共享您的具体模式执行, 并执行了 constructor(), 可能会发生一些错误, 因为解码器 不会 在该结构的初始化阶段提供所有参数.

由于增加了 .assign({}) 方法,因此推荐直接使用该方法,而不要通过为 constructor() 提供参数来设置结构中的初始数据:

const player = new Player().assign({ x: 10, y: 10 });

MapSchema 重大修改

MapSchema 之前被视为普通的 JavaScript 对象 ({}). 现在, 它使用内置 Map.

通过使用内置 Map, 与地图密钥顺序相关的问题得到了解决 (#51#70).

但有一些重大修改, 您应该在自己的项目上进行修复.

迭代所有项

之前版本:

for (const key in yourMap) {
    key // map key
    yourMap[key] // map value
}

新版本:

yourMap.forEach((value, key) => {
    key // map key
    value // map value
});

或者, 您可以使用迭代器 map.keys()map.values() 单独迭代地图密钥或值.

获得所有项的总数

之前版本:

const size = Object.keys(this.state.players).length;
console.log("Number of items =>", size);

新版本:

const size = this.state.players.size;
console.log("Number of items =>", size);

获得 MapSchema 的密钥

之前版本:

Object.keys(map)

新版本:

Array.from(map.keys())

获取并设置 MapSchema

这是一项重大修改!仍然 可以使用括号访问器从 MapSchema 获取和设置值. 不过建议使用新的 Map 类方法来代替.

之前版本:

// get with bracket accessor
// (the type of "entry" here is "any")
const entry = yourMap["key"];

// set with bracket accessor
yourMap["key"] = "value";

新版本:

// get with .get() method
// (the type of "entry" matches the type definition)
const entry = yourMap.get("key");

// set with .set() method
yourMap.set("key", "value");

客户端: Schema 回调

TLDR: 仔细检查您在客户端上的所有 onChange 回调.您可能需要为子结构添加更多 onChange 回调.

Schema 引用上的 onChange

之前版本: 当更深层的子容器发生变更时, 父容器的字段就会受触发发生变化.

// Server-side
state.player.position.x = 10;

// Client-side
state.player.onChange = function(changes) {
    changes[0].field // "position" is here!
}

新版本: 现在, 变化将 不再传播到 父 Schema 实例. 如果您需要监听 player.position 的变化(并且.position 的类型为 Schema), 您需要在 .position 实例上附加一个 onChang 回调.

// Server-side
state.player.position.x = 10;

// Client-side
state.player.position.onChange = function(changes) {
    changes[0].field // "x" is here!
}

onChange on collections (ArraySchema, MapSchema, etc.)

与前面的例子类似,如果子集合是一个 Schema 实例,则 onChange 不再会触发. onChange 只会因基元值而触发.

之前版本:

state.arrayOfSchemas.onChange = function(value, key) {
    console.log(value, "has changed at", key);
}

state.arrayOfPrimitives.onChange = function(value, key) {
    console.log(value, "has changed at", key);
}

新版本:

state.arrayOfSchemas.onAdd = function(value, key) {
    value.onChange = function(changes) {
        console.log("List of changes", changes);
    }
}
state.arrayOfSchemas.onChange = function(value, key) {
    // you can remove this callback, as it is never going to be called.
}

state.arrayOfPrimitives.onChange = function(value, key) {
    // here remains the same for primitive values (string, number, boolean)
    console.log(value, "has changed at", key);
}

Back to top