我正在创建一个记分牌,其中包含一个每秒更新一次的计时器。它完美地运作问题是记分板每隔2-5秒就会出现故障(闪烁)。这是我的代码:
Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
public void run() {
ScoreboardManager manager = Bukkit.getScoreboardManager();
final Scoreboard board = manager.getNewScoreboard();
final Objective o = board.registerNewObjective("Timer", "dummy");
o.setDisplayName(ChatColor.DARK_GRAY + "" + ChatColor.BOLD + "-- " + ChatColor.DARK_RED + ChatColor.BOLD + "Minecraft" + ChatColor.DARK_GRAY + ChatColor.BOLD + " --");
o.setDisplaySlot(DisplaySlot.SIDEBAR);
Score score = o.getScore(ChatColor.GOLD + "Chest Restock in:");
score.setScore(10);
if (seconds < 0 ){
seconds = 118;
minutes--;
}
long second = seconds/2;
int s = Math.round(second);
if (seconds > 18 ){
Score score1 = o.getScore(minutes+":"+s);
score1.setScore(9);
} else {
Score score1 = o.getScore(minutes+":0"+s);
score1.setScore(9);
}
Score score2 = o.getScore(" ");
score2.setScore(8);
Score scoreName = o.getScore(""+ChatColor.GOLD + ChatColor.BOLD + player.getName());
scoreName.setScore(7);
Score score3 = o.getScore(" ");
score3.setScore(6);
int kills = kdData.getInt(player.getName() + ".Kills");
Score score4 = o.getScore("Kills: " + ChatColor.DARK_RED + kills);
score4.setScore(5);
Score score5 = o.getScore(" ");
score5.setScore(4);
int deaths = kdData.getInt(player.getName() + ".Deaths");
Score score6 = o.getScore("Deaths: " + ChatColor.DARK_RED + deaths);
score6.setScore(3);
Score score7 = o.getScore(" ");
score7.setScore(2);
double killsD = kdData.getInt(player.getName() + ".Kills");
double deathsD = kdData.getInt(player.getName() + ".Deaths");
if( kills >= 0 && deaths == 0){
double kd = killsD/1;
Score score8 = o.getScore("KD Ratio: " + ChatColor.GOLD + kd);
score8.setScore(1);
}
if( kills >= 0 && deaths > 0){
double kd = killsD/deathsD;
double kdRounded = Math.round(kd * 100.0) / 100.0;
Score score8 = o.getScore("KD Ratio: " + ChatColor.GOLD + String.valueOf(kdRounded));
score8.setScore(1);
}
Score score9 = o.getScore(" ");
score9.setScore(0);
player.setScoreboard(board);
}
}, 0, 20L);
}
基本上我每秒都会创建一个新的记分牌。是否有可能每秒更新一次计时器(Chest Restock in :)?我该怎么做才能阻止这个故障?谢谢! :)
答案 0 :(得分:1)
在不必创建新的棋盘和/或目标的情况下更改记分牌中的得分值是完全可能的,并且消除了我所知道的闪烁(我假设创建了许多新的记分牌是导致闪烁)。您需要跟踪每个Objective
的{{1}},然后您可以使用这些Player
来检索和修改各个Score
值。更改值后,将自动为客户端更新显示,而无需重新设置播放器的记分板。下面是一个任务的示例,可以在任何时间间隔运行以更新具有多个分数的常规显示(不应闪烁):
public class ScoreboardUpdater implements Runnable {
// A map that associates a player's ID to their objective (you can of course use something completely different)
private static HashMap<UUID, Objective> playerObjectiveMap = new HashMap<UUID, Objective>();
public void run() {
for (Player player : Bukkit.getOnlinePlayers()) { // Loop through all plauers
UUID id = player.getUniqueId(); // Get their unique ID
if (!playerObjectiveMap.containsKey(id)) { // If they don't have an objective yet
Scoreboard board = Bukkit.getScoreboardManager().getNewScoreboard(); // Get a new scoreboard
Objective objective = board.registerNewObjective("test", "dummy"); // Create the objective that will contain the scores
objective.setDisplaySlot(DisplaySlot.SIDEBAR); // Move the display to the sidebar
objective.setDisplayName("Name of Display"); // Name the display something
// Here you can optionally initialize the score values for the player by using the getScore() method like below
player.setScoreboard(board); // Display the initial scoreboard to the player
playerObjectiveMap.put(id, objective); // Add the objective to the map
}
Objective objective = playerObjectiveMap.get(id); // Retrieve objective for the player from map
// Now that you have the player's objective, you can change the value of any scores!
Score score = objective.getScore("Example Score: "); // Create a score
score.setScore((int) (Math.random() * 10)); // Set a value (automatically updates for the client)
Score score2 = objective.getScore("Another Score: "); // Create another score
score2.setScore((int) (Math.random() * 50)); // Update
}
}
}
然后您将安排此任务:
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new ScoreboardUpdater(), 0, 20L);
我将这种方法用于记分板,每次刻度更新一个值(每秒20次)以创建动画,它似乎工作得相当好,没有任何闪烁。
答案 1 :(得分:0)
记分牌故障是由客户端或服务器延迟引起的,除非您非常清楚地记录您的记分板代码,否则无法解决此问题。任何更大的服务器/网络都会有记分牌故障。
答案 2 :(得分:0)
您可以毫无理由地在runnable中创建新的记分板,因为它可以是在runnable外部定义但在runnable中更新的相同记分板。