Skip to main content

排行榜开发指南 · JavaScript

Demo

您可以通过查看 Demo 感受排行榜功能。

安装 SDK

排行榜是存储 SDK 中的一个模块,要在 JavaScript 运行环境中使用排行榜功能,需要安装存储 SDK,请参考 JavaScript SDK 安装指南

SDK 中的类

SDK 提供了对排行榜、成绩与用户的抽象。在开始之前,请确认您已阅读 排行榜功能介绍,本文中将不再具体解释相关的概念。

AV.Leaderboard

AV.Leaderboard 类是对排行榜的抽象。Leaderboard 实例有以下属性:

属性类型说明
statisticNamestring所排名的成绩名字
orderAV.LeaderboardOrder排序
updateStrategyAV.LeaderboardUpdateStrategy成绩更新策略
versionChangeIntervalAV.LeaderboardVersionChangeInterval自动重置周期
versionnumber版本
nextResetAtDate计划下次重置时间
createdAtDate创建时间

Statistic

排行榜是对用户的成绩进行排名的结果。SDK 提供了一个 Statistic 类来表示成绩。Statistic 实例有以下属性:

属性类型说明
namestring成绩名字,对应排行榜的 statisticName
valuenumber成绩值

Ranking

排行榜排序的结果是一个数组,数组的成员是一个叫 Ranking 的结构:

属性类型说明
ranknumber排名,从 0 开始
userAV.User拥有该成绩的用户
valuenumber该用户的成绩
includedStatisticsStatistic[]该用户的其他成绩

AV.User

排行榜中的用户指的是 LeanCloud 数据存储服务用户系统中的用户。在客户端,只有登录后才能更新当前登录用户的成绩。您可以通过 内建账户指南了解更多用户系统的功能与用法。

用户成绩管理

更新成绩

当用户完成了一局游戏后,你可以使用 SDK 的 updateStatistic 方法更新该用户的成绩。

AV.Leaderboard.updateStatistics(AV.User.current(), {
score: 3458,
kills: 28,
}).then(function(statistics) {
// statistics 是更新后你的最好/最新成绩
}).catch(console.error);

updateStatistic 方法的第二个参数是一个 key-value 的对象,key 为要更新的 statisticName,value 为要更新的成绩。你可以一次更新多个不同的成绩。

caution

更新成绩 API 需要用户登录,且用户只能更新自己的成绩。也可使用 masterKey 更新任意用户的成绩。

强制更新成绩

有些情况下,你会想要绕过排行榜的 更新策略 强制更新用户的成绩,你可以使用 overwrite 参数实现这一需求:

AV.Leaderboard.updateStatistics(AV.User.current(), { score: 0 }, {
overwrite: true,
}).then(function(statistics) {
// score 会被强制更新为 0
}).catch(console.error);

查询成绩

你可以通过 getStatistics 方法查询某用户的某些成绩:

// 当前玩家需要先登录
AV.User.logIn('playerA', 'passwordA').then((loggedInUser) => {
// 查询另一个玩家在排行榜中的成绩
var otherUser = AV.Object.createWithoutData(AV.User, '5cee072ac8959c0069f62ca8');
return AV.Leaderboard.getStatistics(otherUser, {statisticNames: ['score', 'kills']});
}).then(function(statistics) {
// statistics 是查询的成绩结果
}).catch(function (error) {
// 异常处理
});

你也可以省略 statisticNames 选项用来查询某用户的所有成绩:

// 当前玩家需要先登录
AV.User.logIn('playerA', 'passwordA').then((loggedInUser) => {
// 查询另一个玩家在排行榜中的成绩
var otherUser = AV.Object.createWithoutData(AV.User, '5cee072ac8959c0069f62ca8');
return AV.Leaderboard.getStatistics(otherUser)
}).then(function(statistics) {
// statistics 是查询的成绩结果
}).catch(function (error) {
// 异常处理
});

获取排行榜结果

SDK 提供了两种获取排行榜结果的 API:

方法作用
Leaderboard#getResults获取指定区间的排名
Leaderboard#getResultsAroundUser获取指定用户附近的排名

获取指定区间的排名

获取排行榜结果最常见的使用场景是获取排名前 N 的用户成绩。

var leaderboard = AV.Leaderboard.createWithoutData('score');
leaderboard.getResults({
limit: 10,
skip: 0,
}).then(function(rankings) {
// rankings 为前 10 的排名结果
}).catch(console.error);

Leaderboard#getResults 方法的第一个参数包含以下选项:

选项名类型说明
limitnumber限制返回的结果数量
skipnumber指定从某个位置开始获取,与 limit 一起可以实现翻页
selectUserKeysstring[]指定返回的 Ranking 中的 user 需要包含的属性
includeStatisticsstring[]指定返回的 Ranking 中需要包含的其他成绩
versionnumber指定返回某个历史版本的成绩

默认情况下返回的排行榜结果中的 user 是一个只有 id 属性的 AV.User Pointer。如果想要想下面这个例子一样,在排行榜结果中显示用户名或者其他的用户属性(对应 _User 表中的属性),那么需要使用 selectUserKeys 选项。

排名UsernameAgeScore↓
0Genji353458
1Lúcio263252
2D.Va193140
var leaderboard = AV.Leaderboard.createWithoutData('score');
leaderboard.getResults({
limit: 10,
selectUserKeys: ['username', 'age'],
}).then(function(rankings) {
// ranking 的 user 将包含 username 与 age 属性
}).catch(console.error);

类似的,如果想要在排行榜结果中包含用户的其他成绩,可以使用 includeStatistics 选项。

排名UsernameScore↓Kills
0Genji345828
1Lúcio32522
2D.Va314031
var leaderboard = AV.Leaderboard.createWithoutData('score');
leaderboard.getResults({
limit: 10,
includeStatistics: ['kills'],
}).then(function(rankings) {
// 可以在 ranking 的 includedStatistics 属性中得到该用户的 kills 成绩
}).catch(console.error);

获取当前用户附近的排名

另一种常见的需求是获取当前登录用户附近的排名:

排名UsernameScore↓
24Bastion716
25 (You)Widowmaker698
26Hanzo23
var leaderboard = AV.Leaderboard.createWithoutData('score');
leaderboard.getResultsAroundUser({
limit: 3,
}).then(function(rankings) {
// rankings 为当前用户附近的 3 条排名结果
}).catch(console.error);

Leaderboard#getResultsAroundUser 方法的第一个参数包含以下选项:

选项名类型说明
limitnumber限制返回的结果数量,当前用户会在结果的中间位置
selectUserKeysstring[]指定返回的 Ranking 中的 user 需要包含的属性
includeStatisticsstring[]指定返回的 Ranking 中需要包含的其他成绩
versionnumber指定返回某个历史版本的成绩

各参数的适用场景与用法与上文 Leaderboard#getResults 的参数类似,不再详述。

获取当前用户的排名

如果仅需要获取当前用户的排名,使用 获取当前用户附近的排名 中的 Leaderboard#getResultsAroundUser 方法并指定 limit 为 1 时即可。

管理排行榜

您可以在控制台的「游戏 - 排行榜 - 数据」页面完成排行榜的创建、重置、修改以及删除等操作。除此之外您也可以通过调用 SDK 的 API 来管理排行榜。

请注意,管理排行榜 API 需要 masterKey,因此只能在服务端等可信任的环境中调用。

创建排行榜

AV.Leaderboard.createLeaderboard({
statisticName: 'score',
order: AV.LeaderboardOrder.DESCENDING,
}, { useMasterKey: true }).then(function(leaderboard) {
// 创建成功得到 leaderboard 实例
}).catch(console.error);

你可以指定以下参数:

参数类型是否可选默认值说明
statisticNamestring所排名的成绩名字
orderAV.LeaderboardOrder排序
updateStrategyAV.LeaderboardUpdateStrategy可选AV.LeaderboardUpdateStrategy.BETTER成绩更新策略
versionChangeIntervalAV.LeaderboardVersionChangeInterval可选AV.LeaderboardVersionChangeInterval.WEEK自动重置周期

详见 创建排行榜 API 文档

caution

创建排行榜接口需要使用 masterKey。

手动重置排行榜

排行榜在创建之后会按照自动重置周期的设置自动定期重置,重置后该排行榜中所有用户的成绩都会被清空,你可以在控制台的历史版本中找到历史版本的归档。你也可以随时调用重置排行榜的接口手动进行重置。

var leaderboard = AV.Leaderboard.createWithoutData('score');
leaderboard.reset({ useMasterKey: true })
.then(function(leaderboard) {
// 重置成功
}).catch(console.error);
caution

重置排行榜接口需要使用 masterKey。

获取排行榜属性

通过这个接口可以获得当前排行榜的属性,例如:重置周期、版本号、更新策略等。

AV.Leaderboard.getLeaderboard('world').then((data) => {
console.log(data);
}).catch(console.error)

修改排行榜属性

排行榜创建后,名字与成绩排序方式不可修改。

自动重置周期可以通过调用以下 API 修改:

var leaderboard = AV.Leaderboard.createWithoutData('score');
leaderboard.updateVersionChangeInterval(
AV.LeaderboardVersionChangeInterval.MONTH,
{ useMasterKey: true }
).then(function(leaderboard) {
// 修改成功
}).catch(console.error);

成绩更新策略可以通过调用以下 API 修改:

var leaderboard = AV.Leaderboard.createWithoutData('score');
leaderboard.updateUpdateStrategy(
AV.LeaderboardUpdateStrategy.LAST,
{ useMasterKey: true }
).then(function(leaderboard) {
// 修改成功
}).catch(console.error);
caution

修改排行榜属性接口需要使用 masterKey。

删除排行榜

var leaderboard = AV.Leaderboard.createWithoutData('score');
leaderboard.destroy({ useMasterKey: true })
.then(function() {
// 删除成功
}).catch(console.error);
caution
  • 删除排行榜会删除该排行榜的所有数据,包括当前数据及所有历史版本归档。
  • 删除排行榜接口需要使用 masterKey。