Java Bukkit记分牌行为怪异
我有这样一个记分板:Java Bukkit记分牌行为怪异,java,bukkit,Java,Bukkit,我有这样一个记分板: 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.get
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);
}
每当我尝试更新它时,它就是不起作用,顺便说一句,我的记分板是一个“奇特”的,所以它应该看起来像:
时间=时间6因为你以一种非传统的方式使用记分牌,事情肯定会变得棘手。所谓“花式”,我假设你指的是在左侧相邻显示分数名称和值的记分板,这是通过将实际分数值放在分数的名称
字符串中来完成的(就像你已经做的那样)
代码的问题在于,您实际上并没有更改现有分数条目的值(因为该值设置为6以使条目保持在显示的同一行中),而是在每次更新显示时创建一个新的分数条目,因为分数条目是由其名称而不是分数值标识的(这是必需的,以便不同的分数条目可以具有相同的值,例如,玩家可以具有值为2的“银行余额”分数和值为2的“死亡数量”分数)
例如,如果不是这种情况,您的名为“Time=14”且分数值为6的新分数条目将覆盖名为“Time=15”的先前分数条目,因为分数值相同,但情况并非如此
当我测试您的代码片段时,添加了更多的行(分数条目),直到显示达到最大容量。我只能假设这就是您所说的代码“行为怪异”的意思,因为您没有详细说明代码的预期和观察结果
您需要删除以前的带有过期值的分数条目。因为API不打算以这种方式使用,所以不能简单地从目标中删除分数条目(重置分数不会删除整个条目)
因此,每当您想要更新单个“花式”分数条目时,您需要创建一个带有新目标等的新计分板。这也意味着计分板中显示的所有分数都需要单独跟踪,并在任何其他“花式”分数更新时重新添加和设置到新计分板
对您的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);
}
请注意,此方法只解决了添加更多条目的直接问题,如果您想要更多的“花式”条目,甚至可能是正常的分数条目,则所有这些条目都需要分别处理
所有这些额外的工作以及在屏幕右侧始终显示无意义的数字/值似乎只是为了在分数名称和值之间删除一点空白而进行了一次大的权衡
其他一些提示:您不需要每次为新的玩家启动记分板时都更新sbManager
变量,因为管理者始终是同一个对象,所以使用Bukkit.getScoreboardManager()
一次就足够了。Bukkit.getOfflinePlayer(字符串)
根据离线玩家的用户名获取他们的信息。为什么要尝试检索名为“Time=15”的玩家信息?我相当确定这将始终返回null
。不,它是有效的,因为离线玩家可以是任何东西,甚至是除了空格以外的不可见字符,它不会得到真正的离线玩家。它只是bukkit以某种方式“创建”的假玩家……你可以简单地使用obj.getScore(“Time=“+Time”)
。这同样有效,而且对于阅读您的代码的人来说,也不太容易混淆。
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);
}