v0.9.4: added the ability to play a variable list of music tracks

This commit is contained in:
Evan Debenham 2021-07-03 20:20:51 -04:00
parent f547b8a0b0
commit c50c012f8f

View File

@ -24,6 +24,10 @@ package com.watabou.noosa.audio;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.watabou.noosa.Game; import com.watabou.noosa.Game;
import com.watabou.utils.DeviceCompat; import com.watabou.utils.DeviceCompat;
import com.watabou.utils.Random;
import java.util.ArrayList;
import java.util.Collections;
public enum Music { public enum Music {
@ -37,6 +41,11 @@ public enum Music {
private boolean enabled = true; private boolean enabled = true;
private float volume = 1f; private float volume = 1f;
String[] trackList;
float[] trackChances;
private final ArrayList<String> trackQueue = new ArrayList<>();
boolean shuffle = false;
public synchronized void play( String assetName, boolean looping ) { public synchronized void play( String assetName, boolean looping ) {
//iOS cannot play ogg, so we use an mp3 alternative instead //iOS cannot play ogg, so we use an mp3 alternative instead
@ -51,22 +60,107 @@ public enum Music {
stop(); stop();
lastPlayed = assetName; lastPlayed = assetName;
trackList = null;
this.looping = looping; this.looping = looping;
this.shuffle = false;
if (!enabled || assetName == null) { if (!enabled || assetName == null) {
return; 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 { try {
player = Gdx.audio.newMusic(Gdx.files.internal(assetName)); player = Gdx.audio.newMusic(Gdx.files.internal(track));
player.setLooping(looping); player.setLooping(looping);
player.setVolume(volume); player.setVolume(volume);
player.play(); player.play();
if (listener != null) {
player.setOnCompletionListener(listener);
}
} catch (Exception e){ } catch (Exception e){
Game.reportException(e); Game.reportException(e);
player = null; player = null;
} }
} }
public synchronized void mute() { public synchronized void mute() {
@ -112,9 +206,13 @@ public enum Music {
stop(); stop();
} else } else
if (!isPlaying() && value) { if (!isPlaying() && value) {
if (trackList != null){
playTracks(trackList, trackChances, shuffle);
} else {
play(lastPlayed, looping); play(lastPlayed, looping);
} }
} }
}
public synchronized boolean isEnabled() { public synchronized boolean isEnabled() {
return enabled; return enabled;