0

OK i am making a minecraft java plugin and it plays a song to the player using preset sounds it is triggers with:
player.playSound(player.getLocation(), Sound.NOTE_BASS, 2, 10);

And i want it to want to make it sing lyrics for example hammer time so it would look like this:

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 

and so on ..... So i dont want to use the Thread.sleep(100) or wait() because they would need me to use a try, catch statement witch would not work because i need it to act as a big script i carnt have a bunch of try catch in the script. so i guess i am asking is there any other ways for me to do this ?

Gerard2202
  • 151
  • 6
  • 18

2 Answers2

2

You could compromise and use one try-catch:

try {
    player.playSound(...);
    Thread.sleep(100);
    player.playSound(...);
    Thread.sleep(100);
    /* etc */
} catch (InterruptedException e) {
    e.printStackTrace();
    // handle exception
}
Jeffrey
  • 44,417
  • 8
  • 90
  • 141
  • yer i thought of that after but to be honest i dont fully under stand try and catch – Gerard2202 Aug 25 '13 at 00:46
  • @Gerard2202 What don't you understand? – Jeffrey Aug 25 '13 at 00:48
  • i just dont fully get how they work or what they are for i started java a week or 2 ago and i am making lots of programs and i just try not to use them i am learning just from trying to fix errors – Gerard2202 Aug 25 '13 at 00:52
  • @Gerard2202 Here's a good [tutorial](http://docs.oracle.com/javase/tutorial/essential/exceptions/) that explains all about exceptions and how `try-catch-finally` works. – Jeffrey Aug 25 '13 at 00:56
  • @Gerard2202 Don't use `Thread.sleep` in a Bukkit plugin unless you want the whole server to freeze. – Tyler Aug 27 '13 at 16:24
2

You should use the Bukkit Scheduler. Since you want to make this as script like as possible, here is how I would suggest you do it. It does use something called an interface, which you probably haven't gotten to, but you don't have to understand it right now to use it.

Make a new class that holds all the information you need for your note and 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);
    }
}

Now you can use this class in something called a scheduledSyncDelayedTask() (Long name, amazing results:P). With it you can send players notes in one-line statements like this:

        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);

This method doesn't really allow for chord structures though, so if you want to do that, you can create a class that will basically hold a list of notes as follows:

    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;
    }
}

Then you make the thing that implements Runnable like before, but now use a for loop to play all the notes at once so you get a chord:

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);
        }
    }
}

Now you can use this by doing this:

        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);

If you find that you're using particular chords often, you can make them as variables like this:

        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...
            };

If you find AsychDelayedTask, that is a Deprecated method which means that Bukkit is phasing it out. Don't use it. Also, the Bukkit scheduler has a repeating task method that allows you to easily repeat an action over and over. This method is scheduleSyncRepeatingTask(). With this you need to cancel the task, otherwise you'll risk null pointers when the player logs off, or does something that causes an error. If you need to cancel either the delayed task or the repeating task, use this:

sched.cancelTask(id);

I think that's about everything. Hope it helps. :)

Kammeot
  • 469
  • 7
  • 18