提供: Minecraft Modding Wiki
2019年5月31日 (金) 22:04時点における119.224.175.251 (トーク)による版 (スコアボードシステムの使い方)
移動先: 案内検索

スコアボードシステムの使い方

MinecraftのScoreboardシステムを、Bukkit API経由で使用する方法をまとめます。 このチュートリアルは、こちらの内容を参考に作成しています。

基本的に、Bukkit APIから使用できるScoreboardシステムは、 バニラのサーバーコマンド /scoreboard で実施できることとほとんど同じです。 このチュートリアルを理解するためには、/scoreboard コマンドを試して、 Scoreboardシステムの仕様をよく理解することが一番の近道です。 コマンドの使い方は、こちらこちらを参考にしてみて

スコアボードシステムの基本的な使い方

まず、ScoreboardManager を取得します。

ScoreboardManager manager = Bukkit.getScoreboardManager();

次に、Scoreboard を取得します。

Scoreboard board = manager.getMainScoreboard();

Scoreboard に、新しいチームを登録します。

Team team = board.registerNewTeam("teamname");

そして、登録されたチームの設定をいろいろ変更します。

// プレイヤーを追加します。
team.addPlayer(player);

// プレイヤーを削除します。
team.removePlayer(player);

// prefixを登録します。これは、TABキーを押したときのプレイヤーリストと、
// 頭の上のプレイヤー名で、該当チームに所属するプレイヤーの名前の"前"に、
// 指定した文字列が付きます。
// 表示欄は狭いため、長い文字列を指定することは避けるべきです。
// なお、ChatColorによる装飾が指定可能です。
// 例)team.setPrefix(ChatColor.RED.toString());
team.setPrefix("prefix");

// suffixを登録します。これは、TABキーを押したときのプレイヤーリストと、
// 頭の上のプレイヤー名で、該当チームに所属するプレイヤーの名前の"後"に、
// 指定した文字列が付きます。
// なお、prefixでChatColorを使用した場合、suffixでRESETを指定することを推奨します。
// 例)team.setPrefix(ChatColor.RESET.toString());
team.setSuffix("suffix");

// チームの表示名を指定します。
team.setDisplayName("display name");

// チームメンバー同士の攻撃ができるかどうかを設定します。
// true で攻撃が有効になり、false で攻撃が無効になります。
team.setAllowFriendlyFire(false);

// 透明化しているチームメンバーを見えるようにするかどうかを設定します。
// true で透明化しているチームメンバーが見えるようになり、
// false で誰からも見えなくなります。
team.setCanSeeFriendlyInvisibles(true);

"dummy"というCriteriaを設定して、"test"という名前の新しいObjectiveを作成します。

Objective objective = board.registerNewObjective("test", "dummy");

新しく登録したObjectiveの設定も、いろいろ変更してみましょう。

// Objective の表示名を設定します。
objective.setDisplayName("Display Name");

// Objectiveをどこに表示するかを設定します。
// SIDEBAR、PLAYER_LIST、BELOW_NAME が指定できます。
objective.setDisplaySlot(DisplaySlot.BELOW_NAME);

特定のプレイヤーに対するObjectiveでの点数を設定します。

// ※ CraftBukkit 1.7.5 以前の場合
Score score = objective.getScore(player);
score.setScore(42);

// ※ CraftBukkit 1.7.8 以降の場合は、getScoreメソッドにはStringを使ってください。
Score score = objective.getScore(player.getName());
score.setScore(42);

ここまでを実装して設定することで、下のスクリーンショットのように表示が確認できていると思います。

Scoreboard1.png

特定のプレイヤーのスコアをリセットするには、次のようにします。

// ※ CraftBukkit 1.7.5 以前の場合
board.resetScores(player);

// ※ CraftBukkit 1.7.8 以降の場合
board.resetScores(player.getName());

専用のスコアボードシステムの取得と設定

メインのScoreboardシステムを使用してしまうと、他で設定している得点内容を上書きしてしまったり、 Objectiveの名前が衝突してしまったりしないか、心配があります。

自身のプラグイン専用に、Scoreboardシステムを取得したい場合は、 最初のgetMainScoreboard()をgetNewScoreboard()にしてください。

Scoreboard board = manager.getNewScoreboard();

専用のScoreboardシステムでは、デフォルトで表示されません。 各プレイヤーに、自分のプラグインで作成したスコアボードを表示したい時は、setScoreboardを使用してスコアボードを設定してください。

for ( Player player : Bukkit.getOnlinePlayers() ) {
    player.setScoreboard(board);
}


サイドバーでのカスタム項目の設定

サイドバーにObjectiveを設定している場合、ダミーの項目を登録することで、 カスタム項目を表示することが可能です。 カスタム項目のスコアを登録するには、次のようにします。

// ※ CraftBukkit 1.7.5 以前の場合は、OfflinePlayerを生成して設定してください。
Score score = objective.getScore(Bukkit.getOfflinePlayer(name));
score.setScore(99);

// ※ CraftBukkit 1.7.8 以降の場合は、そのままStringを指定してください。
Score score = objective.getScore(name);
score.setScore(99);

カスタム項目のスコアをリセットするには、次のようにします。

// ※ CraftBukkit 1.7.5 以前の場合
board.resetScores(Bukkit.getOfflinePlayer(name));

// ※ CraftBukkit 1.7.8 以降の場合
board.resetScores(name);


// ※ CraftBukkit 1.7.8 以降の場合
Score score = objective.getScore(ChatColor.GREEN + "kills:");
score.setScore(99);

Scoreboard2.png

簡単な実装例

体力表示プラグイン

各プレイヤーの頭の上に、現在の体力を表示します。 なお、Criteria に "health" を指定した場合、各プレイヤーの体力が増減するたびに、自動的に更新されます。 (プラグイン側から更新を実施する必要はありません。)

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.ScoreboardManager;

/**
 * 各プレイヤーの頭の上に、現在の体力を表示するプラグイン
 */
public class ScoreboardHealthPlugin extends JavaPlugin {

    /** オブジェクティブの名前 */
    private static final String OBJECTIVE_NAME = "showhealth";
    
    /**
     * プラグインが有効化されたときに呼び出されます
     * @see org.bukkit.plugin.java.JavaPlugin#onEnable()
     */
    @Override
    public void onEnable() {
        
        // メインスコアボードを取得します。
        ScoreboardManager manager = Bukkit.getScoreboardManager();
        Scoreboard board = manager.getMainScoreboard();

        // オブジェクティブが既に登録されているかどうか確認し、
        // 登録されていないなら新規作成します。
        Objective objective = board.getObjective(OBJECTIVE_NAME);
        if ( objective == null ) {
            objective = board.registerNewObjective(OBJECTIVE_NAME, "health");
            objective.setDisplaySlot(DisplaySlot.BELOW_NAME);
            objective.setDisplayName("/ 20");
        }
        
        // 全プレイヤーの現在の体力を反映します
        for (Player player : Bukkit.getOnlinePlayers()) {
            objective.getScore(player).setScore((int)player.getHealth());
        }
    }
}

チーム分けプラグイン

プレイヤーを2チームに分けるサンプルです。

TABキーの名前リストと、頭の上の名前表示に、チームの色が付きます。 また、チームメンバー間の攻撃が無効になります。

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.ScoreboardManager;
import org.bukkit.scoreboard.Team;

/**
 * 2チームに分けるためのプラグイン
 */
public class ScoreboardTeamPlugin extends JavaPlugin {
    
    /** 赤チームの名前 */
    private static final String TEAM_RED_NAME = "team_red";
    /** 青チームの名前 */
    private static final String TEAM_BLUE_NAME = "team_blue";
    
    /** 赤チーム */
    private Team teamRed;
    /** 青チーム */
    private Team teamBlue;
    
    /**
     * このメソッドは、プラグインが有効化されたときに呼び出されます
     * @see org.bukkit.plugin.java.JavaPlugin#onEnable()
     */
    @Override
    public void onEnable() {
 
        // メインスコアボードを取得します。
        ScoreboardManager manager = Bukkit.getScoreboardManager();
        Scoreboard board = manager.getMainScoreboard();

        // チームが既に登録されているかどうか確認し、
        // 登録されていないなら新規作成します。
        teamRed = board.getTeam(TEAM_RED_NAME);
        if ( teamRed == null ) {
            teamRed = board.registerNewTeam(TEAM_RED_NAME);
            teamRed.setPrefix(ChatColor.RED.toString());
            teamRed.setSuffix(ChatColor.RESET.toString());
            teamRed.setDisplayName("team red");
            teamRed.setAllowFriendlyFire(false);
        }
        teamBlue = board.getTeam(TEAM_BLUE_NAME);
        if ( teamBlue == null ) {
            teamBlue = board.registerNewTeam(TEAM_BLUE_NAME);
            teamBlue.setPrefix(ChatColor.BLUE.toString());
            teamBlue.setSuffix(ChatColor.RESET.toString());
            teamBlue.setDisplayName("team blue");
            teamBlue.setAllowFriendlyFire(false);
        }
    }

    /**
     * このメソッドは、コマンドが実行された時に呼び出されます
     * @see org.bukkit.plugin.java.JavaPlugin#onCommand(org.bukkit.command.CommandSender, org.bukkit.command.Command, java.lang.String, java.lang.String[])
     */
    @Override
    public boolean onCommand(
            CommandSender sender, Command command, String label, String[] args) {
        
        // コマンドの引数が足りない場合は、エラーを表示します
        if ( args.length <= 1 ) {
            sender.sendMessage("コマンドの引数が足りません。");
            sender.sendMessage("'/" + label + " (チーム名) (プレイヤー名)' のように実行してください。");
            return true;
        }
        
        // 1番目の引数に無効な文字列が指定された時に、エラーを表示します
        if ( !args[0].equalsIgnoreCase("red") && !args[0].equalsIgnoreCase("blue") ) {
            sender.sendMessage("指定されたチーム名 " + args[0] + " が無効です。");
            sender.sendMessage("red または blue を指定してください。");
            return true;
        }
        
        // 2番目の引数に無効なプレイヤー名が指定された時に、エラーを表示します
        Player target = Bukkit.getPlayerExact(args[1]);
        if ( target == null ) {
            sender.sendMessage("プレイヤー " + args[1] + " が見つかりません。");
            return true;
        }

        // 指定されたプレイヤーをチームに加えます
        Team team;
        if ( args[0].equalsIgnoreCase("red") ) {
            team = teamRed;
        } else {
            team = teamBlue;
        }
        team.addPlayer(target);
        sender.sendMessage("プレイヤー " + args[1] + " を " + args[0] + " に加えました。");
        return true;
    }
}

慣れてきたら、いろいろ工夫してみましょう。
例えば、チームから離脱するコマンドを追加してみてください。

TIPS

オブジェクティブ名には、17文字以上の名前を指定しないでください。
オブジェクティブの表示名には、33文字以上の名前を指定しないでください。
チーム名には、17文字以上の名前を指定しないでください。
チームの表示名には、33文字以上の名前を指定しないでください。
チームのprefix、suffixには、33文字以上の名前を指定しないでください。
サイドバーにダミーで登録するオフラインプレイヤー名には、17文字以上の名前を指定しないでください。

メインスコアボードを強制的にクリアするには、CraftBukkitを停止して、「world/data/scoreboard.dat」ファイルを削除してください。