210 lines
4.0 KiB
JavaScript
210 lines
4.0 KiB
JavaScript
"use strict";
|
|
|
|
/**
|
|
* @constructor
|
|
*/
|
|
function AudioManager(enabled)
|
|
{
|
|
this.muted = !enabled;
|
|
this.works = true;
|
|
|
|
if(!window.Audio)
|
|
{
|
|
this.works = false;
|
|
}
|
|
// save the planet, use ogg/vorbis
|
|
else if(!new Audio().canPlayType("audio/ogg; codecs=vorbis"))
|
|
{
|
|
this.works = false;
|
|
}
|
|
//this.works = false;
|
|
|
|
this.playing = [];
|
|
|
|
// files that are enqueued when the game is muted, so
|
|
// they can be played as soon as someone unmutes
|
|
this.playQueue = [];
|
|
}
|
|
|
|
/**
|
|
* @param {boolean=} loop
|
|
* @param {boolean=} once
|
|
* @param {number=} volume
|
|
* @param {number=} startTime
|
|
*/
|
|
AudioManager.prototype.play = function(file, loop, once, volume, startTime)
|
|
{
|
|
if(!this.works)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(this.muted)
|
|
{
|
|
this.playQueue.push([new Date, Array.toArray(arguments)]);
|
|
return;
|
|
}
|
|
|
|
var existing = this.playing.filter(Function.byIndex("file", file)),
|
|
audioObject = existing.find(playable),
|
|
audio;
|
|
|
|
function playable(obj)
|
|
{
|
|
return (obj.audio.ended || obj.audio.paused) != !!once;
|
|
}
|
|
|
|
if(audioObject)
|
|
{
|
|
// if the audio ended and can be player more than once
|
|
// OR it's running and shouldn't be played more than once,
|
|
// restart it
|
|
audio = audioObject.audio;
|
|
}
|
|
else
|
|
{
|
|
audio = new Audio(this.path + file);
|
|
|
|
this.playing.push({
|
|
audio: audio,
|
|
file: file,
|
|
});
|
|
}
|
|
|
|
var dontPlay = false;
|
|
|
|
if(startTime !== undefined)
|
|
{
|
|
// audio.duration is NaN if it's not known yet, so this
|
|
// check should be safe
|
|
if(audio.duration && (audio.duration < startTime))
|
|
{
|
|
// we're too late
|
|
dontPlay = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
startTime = 0;
|
|
}
|
|
|
|
if(!dontPlay)
|
|
{
|
|
if(volume !== undefined)
|
|
{
|
|
audio.volume = volume;
|
|
}
|
|
|
|
if(audio.readyState < 4)
|
|
{
|
|
audio.addEventListener("loadedmetadata", function()
|
|
{
|
|
audio.currentTime = startTime;
|
|
});
|
|
}
|
|
else
|
|
{
|
|
audio.currentTime = startTime;
|
|
}
|
|
|
|
audio.loop = loop;
|
|
audio.play();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @param {function()=} onload
|
|
* @param {function()=} onerror
|
|
*/
|
|
AudioManager.prototype.preload = function(file, onload, onerror)
|
|
{
|
|
// no check is made if the game is muted
|
|
|
|
if(this.works && !this.muted)
|
|
{
|
|
var existing = this.playing.find(Function.byIndex("file", file));
|
|
|
|
if(existing)
|
|
{
|
|
if(onload)
|
|
{
|
|
setTimeout(onload, 0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
var audio = new Audio(this.path + file);
|
|
|
|
audio.muted = this.muted;
|
|
|
|
if(onload)
|
|
{
|
|
audio.addEventListener("canplaythrough", onload);
|
|
|
|
if(onerror)
|
|
{
|
|
audio.addEventListener("error", onerror);
|
|
}
|
|
}
|
|
|
|
audio.load();
|
|
|
|
this.playing.push({
|
|
audio: audio,
|
|
file: file,
|
|
});
|
|
|
|
return audio;
|
|
}
|
|
else
|
|
{
|
|
setTimeout(onload, 0);
|
|
}
|
|
};
|
|
|
|
AudioManager.prototype.stop = function(file)
|
|
{
|
|
if(this.works)
|
|
{
|
|
var audioObjs = this.playing.filter(Function.byIndex("file", file));
|
|
|
|
audioObjs.forEach(stop);
|
|
}
|
|
|
|
function stop(obj)
|
|
{
|
|
obj.audio.pause();
|
|
//obj.currentTime = 0;
|
|
}
|
|
};
|
|
|
|
AudioManager.prototype.toggleMute = function()
|
|
{
|
|
if(this.works)
|
|
{
|
|
var muted = this.muted = !this.muted;
|
|
|
|
this.playing.forEach(setMute);
|
|
}
|
|
|
|
if(!this.muted)
|
|
{
|
|
var self = this;
|
|
|
|
this.playQueue.forEach(function(args)
|
|
{
|
|
args[1][4] = (Date.now() - args[0]) / 1000;
|
|
self.play.apply(self, args[1]);
|
|
});
|
|
|
|
this.playQueue = [];
|
|
}
|
|
|
|
function setMute(audioObj)
|
|
{
|
|
audioObj.audio.muted = muted;
|
|
}
|
|
};
|
|
|
|
|