0

好的,我正在制作一个 minecraft java 插件,它使用触发的预设声音向播放器播放歌曲:
player.playSound(player.getLocation(), Sound.NOTE_BASS, 2, 10);

我希望它让它唱歌词,例如锤子时间,所以它看起来像这样:

Bukkit.broadcastMessage(ChatColor.DARK_PURPLE +"[Server]" +ChatColor.AQUA + "Na Na Na Na, Na Na");
player.playSound(player.getLocation(), Sound.NOTE_BASS, 1, 10);
player.playSound(player.getLocation(), Sound.NOTE_BASS, 2, 10);
player.playSound(player.getLocation(), Sound.NOTE_BASS, 3, 10);
player.playSound(player.getLocation(), Sound.NOTE_BASS, 4, 10);
player.playSound(player.getLocation(), Sound.NOTE_BASS, 1, 10);
//a sleep statement here 

等等.....所以我不想使用Thread.sleep(100)orwait()因为他们需要我使用try,catch声明女巫将不起作用,因为我需要它作为一个大脚本我没有一堆 try catch 在脚本。所以我想我在问我还有其他方法可以做到这一点吗?

4

2 回答 2

2

您可以妥协并使用一个try-catch

try {
    player.playSound(...);
    Thread.sleep(100);
    player.playSound(...);
    Thread.sleep(100);
    /* etc */
} catch (InterruptedException e) {
    e.printStackTrace();
    // handle exception
}
于 2013-08-25T00:40:52.710 回答
2

您应该使用 Bukkit 调度程序。既然你想尽可能地把它写成脚本,我建议你这样做。它确实使用了一种叫做接口的东西,你可能还没有接触过,但你现在不必理解它就可以使用它。

创建一个包含笔记所需的所有信息的新类,并且implements Runnable.

    public class Note implements Runnable {

    private Sound note;
    private Player player;
    private float volume;
    private float pitch;

    public Note(Player player, Sound note, float volume, float pitch) {
        this.player = player;
        this.note = note;
        this.volume = volume;
        this.pitch = pitch;
    }

    @Override
    public void run() {
        player.playSound(player.getLocation(), note, volume, pitch);
    }
}

现在您可以在称为scheduledSyncDelayedTask()(长名称,惊人的结果:P)的东西中使用这个类。有了它,您可以像这样以单行语句向玩家发送注释:

        Player player = Bukkit.getPlayer("InspiredOne");
    BukkitScheduler sched = plugin.getServer().getScheduler();
    long delayInServerTicks  = 20; // There are 20 server ticks per second.
    int id; // Used if you need to cancel the task

    id = sched.scheduleSyncDelayedTask(plugin, new Note(player, Sound.NOTE_BASS, 1, 10), delayInServerTicks);

这种方法实际上并不允许和弦结构,所以如果你想这样做,你可以创建一个基本上包含如下音符列表的类:

    public class Note {
    public Sound note;
    public Player player;
    public float volume;
    public float pitch;

    public Note(Player player, Sound note, float volume, float pitch) {
        this.player = player;
        this.note = note;
        this.volume = volume;
        this.pitch = pitch;
    }
}

然后你像以前一样制作实现 Runnable 的东西,但现在使用 for 循环一次播放所有音符,这样你就得到了一个和弦:

public class runNote implements Runnable {
    private Note[] notes;
    public runNote(Note[] notes) {
        this.notes = notes;
    }

    @Override
    public void run() {
        for(Note note:notes) {
            note.player.playSound(note.player.getLocation(), note.note, note.pitch, note.volume);
        }
    }
}

现在你可以通过这样做来使用它:

        Player player = Bukkit.getPlayer("InspiredOne");
    BukkitScheduler sched = plugin.getServer().getScheduler();
    long delayInServerTicks  = 20; // There are 20 server ticks per second.
    int id; // Used if you need to cancel the task

    id = sched.scheduleSyncDelayedTask(plugin, new runNote(new Note[] {new Note(player, Sound.NOTE_BASS, 1, 10)}), delayInServerTicks);

如果你发现你经常使用特定的和弦,你可以把它们变成这样的变量:

        Note[] chord =new Note[] {
            new Note(player, Sound.NOTE_BASS, 1, 10),
            new Note(player, Sound.NOTE_BASS, 2, 10),
            new Note(player, Sound.NOTE_BASS, 3, 10)
            // ect...
            };

如果您发现AsychDelayedTask,那是一个已弃用的方法,这意味着 Bukkit 正在逐步淘汰它。不要使用它。此外,Bukkit 调度程序具有重复任务方法,可让您轻松地一遍又一遍地重复操作。这种方法是scheduleSyncRepeatingTask()。有了这个你需要取消任务,否则你会在玩家注销时冒空指针的风险,或者做一些导致错误的事情。如果您需要取消延迟任务或重复任务,请使用以下命令:

sched.cancelTask(id);

我认为这就是一切。希望能帮助到你。:)

于 2013-08-25T07:39:55.640 回答