From c50c012f8fb908683dbfd4f33bf00bdb423e6801 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Sat, 3 Jul 2021 20:20:51 -0400 Subject: [PATCH] v0.9.4: added the ability to play a variable list of music tracks --- .../java/com/watabou/noosa/audio/Music.java | 106 +++++++++++++++++- 1 file changed, 102 insertions(+), 4 deletions(-) diff --git a/SPD-classes/src/main/java/com/watabou/noosa/audio/Music.java b/SPD-classes/src/main/java/com/watabou/noosa/audio/Music.java index 37ca75665..cc3337622 100644 --- a/SPD-classes/src/main/java/com/watabou/noosa/audio/Music.java +++ b/SPD-classes/src/main/java/com/watabou/noosa/audio/Music.java @@ -24,6 +24,10 @@ package com.watabou.noosa.audio; import com.badlogic.gdx.Gdx; import com.watabou.noosa.Game; import com.watabou.utils.DeviceCompat; +import com.watabou.utils.Random; + +import java.util.ArrayList; +import java.util.Collections; public enum Music { @@ -36,6 +40,11 @@ public enum Music { private boolean enabled = true; private float volume = 1f; + + String[] trackList; + float[] trackChances; + private final ArrayList trackQueue = new ArrayList<>(); + boolean shuffle = false; public synchronized void play( String assetName, boolean looping ) { @@ -51,22 +60,107 @@ public enum Music { stop(); lastPlayed = assetName; + trackList = null; + this.looping = looping; + this.shuffle = false; if (!enabled || assetName == null) { return; } - + + play(assetName, null); + } + + public synchronized void playTracks( String[] tracks, float[] chances, boolean shuffle){ + + if (tracks == null || tracks.length == 0 || tracks.length != chances.length){ + stop(); + return; + } + + //iOS cannot play ogg, so we use an mp3 alternative instead + if (tracks != null && DeviceCompat.isiOS()){ + for (int i = 0; i < tracks.length; i ++){ + tracks[i] = tracks[i].replace(".ogg", ".mp3"); + } + } + + if (isPlaying() && this.trackList != null && tracks.length == trackList.length){ + + boolean sameList = true; + for (int i = 0; i < tracks.length; i ++){ + if (!tracks[i].equals(trackList[i]) || chances[i] != trackChances[i]){ + sameList = false; + break; + } + } + + if (sameList) return; + } + + stop(); + + lastPlayed = null; + trackList = tracks; + trackChances = chances; + trackQueue.clear(); + + for (int i = 0; i < trackList.length; i++){ + if (Random.Float() < trackChances[i]){ + trackQueue.add(trackList[i]); + } + } + + this.looping = false; + this.shuffle = shuffle; + + if (!enabled || trackQueue.isEmpty()){ + return; + } + + play(trackQueue.remove(0), trackLooper); + } + + private com.badlogic.gdx.audio.Music.OnCompletionListener trackLooper = new com.badlogic.gdx.audio.Music.OnCompletionListener() { + @Override + public void onCompletion(com.badlogic.gdx.audio.Music music) { + if (trackList == null || trackList.length == 0 || player.isLooping()){ + return; + } + + stop(); + + if (trackQueue.isEmpty()){ + for (int i = 0; i < trackList.length; i++){ + if (Random.Float() < trackChances[i]){ + trackQueue.add(trackList[i]); + } + } + if (shuffle) Collections.shuffle(trackQueue); + } + + if (!enabled || trackQueue.isEmpty()){ + return; + } + + play(trackQueue.remove(0), trackLooper); + } + }; + + private synchronized void play(String track, com.badlogic.gdx.audio.Music.OnCompletionListener listener){ try { - player = Gdx.audio.newMusic(Gdx.files.internal(assetName)); + player = Gdx.audio.newMusic(Gdx.files.internal(track)); player.setLooping(looping); player.setVolume(volume); player.play(); + if (listener != null) { + player.setOnCompletionListener(listener); + } } catch (Exception e){ Game.reportException(e); player = null; } - } public synchronized void mute() { @@ -112,7 +206,11 @@ public enum Music { stop(); } else if (!isPlaying() && value) { - play( lastPlayed, looping ); + if (trackList != null){ + playTracks(trackList, trackChances, shuffle); + } else { + play(lastPlayed, looping); + } } }