Bukkit 记分牌行为怪异

Bukkit ScoreBoard Acting Weird

我有一个这样的计分板:

int time = 15;

private ScoreboardManager sbManager;
private Scoreboard scoreBoard; 
private Objective obj;

private Score s0;

public void init(Player player) {
    sbManager = Bukkit.getScoreboardManager();
    scoreBoard = sbManager.getNewScoreboard();

    obj = scoreBoard.registerNewObjective("ScoreBoard", "dummy");

    obj.setDisplaySlot(DisplaySlot.SIDEBAR);
    obj.setDisplayName("Test");

    s0 = obj.getScore(Bukkit.getOfflinePlayer("Time = " + time));

    s0.setScore(6);

    player.setScoreboard(scoreBoard);

    Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable(){

        public void run() {
            time--;
            updateScoreBoard(player);
            System.out.println(time);
        }

    },20, 20);
}

每当我尝试更新它时,它就是不起作用,顺便说一句,我的计分板是 "fancy" 计分板,所以它应该看起来像: 时间 = 时间 6 <- '6' 是默认的我的世界分数。

这是我的更新方法的示例:

public void updateScoreBoard(Player p){ 

    s0 = obj.getScore(Bukkit.getOfflinePlayer("Time =" + time));

    s0.setScore(6);

    p.setScoreboard(scoreBoard);
}

因为您以非常规的方式使用记分板,所以事情一定会变得棘手。 "fancy" 我假设你的意思是记分牌显示分数的名称 值在左侧彼此相邻,这是通过将实际分数值放在乐谱的名称 String(就像您已经完成的那样)。

您的代码的问题具体在于您实际上并没有更改现有分数条目的值(因为该值设置为 6 以使条目保持在显示的同一行中)但创建了一个 new score entry 每次更新显示时,因为 score 条目是由它们的名称而不是它们的 score 值标识的(这是必需的,以便不同的 score 条目可以具有相同的值,例如玩家可以有一个值为 2 的 "bank balance" 分数和一个值为 2 的 "amount of deaths" 分数)。

例如,如果不是这种情况,您的名称为 "Time = 14" 且分数值为 6 的新分数条目将覆盖先前名称为 "Time = 15" 的分数条目,因为分数相同值,但事实并非如此。

当我测试你的代码片段时,添加了更多行(分数条目),直到显示达到最大容量。我只能假设这就是您的代码的意思 "acting weird" 因为您没有详细说明代码的预期和观察到的结果。

您需要删除具有过时值的先前分数条目。因为 API 不打算以这种方式使用,所以不能简单地从 objective 中删除分数条目(重置分数不会删除整个条目)。

因此,每次您想更新单个 "fancy" 分数条目时,您都需要创建一个带有新 objective 等的新记分板。这也意味着记分牌中显示的 所有 分数需要独立跟踪,并在任何其他 "fancy" 分数更新时重新添加和重新设置到新记分牌.

对您的 updateScoreboard 方法所做的这些更改对我有用:

public void updateScoreBoard(Player p) {

    scoreBoard = sbManager.getNewScoreboard();
    obj = scoreBoard.registerNewObjective("ScoreBoard", "dummy");

    obj.setDisplaySlot(DisplaySlot.SIDEBAR);
    obj.setDisplayName("Test");

    s0 = obj.getScore(Bukkit.getOfflinePlayer("Time = " + time));

    s0.setScore(6);

    p.setScoreboard(scoreBoard);
}

请注意,此方法仅解决添加更多条目的直接问题,如果您想要更多"fancy"甚至可能是正常分数条目,所有这些都需要分别处理。

所有这些额外的工作和毫无意义的 numbers/values 总是在显示的右侧似乎是一个巨大的权衡,只是为了删除乐谱名称和值之间的一点空白。

一些其他提示:您不需要每次为新 player 启动记分板时都更新 sbManager 变量,经理始终是同一个对象,因此使用 Bukkit.getScoreboardManager()一次就够了。