mirror of
https://github.com/photonstorm/phaser
synced 2024-11-23 05:03:37 +00:00
The HTML5 Sound Manager would unlock the Sound API on a touch event but only if the audio files were loaded in the first Scene, if they were loaded in a subsequent Scene the audio system would never unlock. It now unlocks only if there are audio files in the cache. Fix #3311
This commit is contained in:
parent
42d2cfdbf4
commit
23285896c0
3 changed files with 178 additions and 77 deletions
|
@ -37,6 +37,7 @@
|
|||
* The RandomDataGenerator classes randomness has been improved thanks to the correct caching of a class property. Fix #3289 (thanks @migiyubi)
|
||||
* The RandomDataGenerator `sign` property had a method collision. Fix #3323 (thanks @vinerz and @samme)
|
||||
* In Arcade Physics World if you collided a group with itself it would call a missing method (`collideGroupVsSelf`), it now calls `collideGroupVsGroup` correctly (thanks @patrickgalbraith)
|
||||
* The HTML5 Sound Manager would unlock the Sound API on a touch event but only if the audio files were loaded in the first Scene, if they were loaded in a subsequent Scene the audio system would never unlock. It now unlocks only if there are audio files in the cache. Fix #3311 (thanks @chancezeus)
|
||||
|
||||
### Updates
|
||||
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
var Class = require('../../utils/Class');
|
||||
|
||||
var BaseSoundManager = require('../BaseSoundManager');
|
||||
var Class = require('../../utils/Class');
|
||||
var HTML5AudioSound = require('./HTML5AudioSound');
|
||||
|
||||
/**
|
||||
|
@ -20,8 +21,12 @@ var HTML5AudioSound = require('./HTML5AudioSound');
|
|||
* @param {Phaser.Game} game - Reference to the current game instance.
|
||||
*/
|
||||
var HTML5AudioSoundManager = new Class({
|
||||
|
||||
Extends: BaseSoundManager,
|
||||
initialize: function HTML5AudioSoundManager (game)
|
||||
|
||||
initialize:
|
||||
|
||||
function HTML5AudioSoundManager (game)
|
||||
{
|
||||
/**
|
||||
* Flag indicating whether if there are no idle instances of HTML5 Audio tag,
|
||||
|
@ -77,6 +82,7 @@ var HTML5AudioSoundManager = new Class({
|
|||
* @since 3.0.0
|
||||
*/
|
||||
this.onBlurPausedSounds = [];
|
||||
|
||||
this.locked = 'ontouchstart' in window;
|
||||
|
||||
/**
|
||||
|
@ -115,6 +121,7 @@ var HTML5AudioSoundManager = new Class({
|
|||
* @since 3.0.0
|
||||
*/
|
||||
this._volume = 1;
|
||||
|
||||
BaseSoundManager.call(this, game);
|
||||
},
|
||||
|
||||
|
@ -132,7 +139,9 @@ var HTML5AudioSoundManager = new Class({
|
|||
add: function (key, config)
|
||||
{
|
||||
var sound = new HTML5AudioSound(this, key, config);
|
||||
|
||||
this.sounds.push(sound);
|
||||
|
||||
return sound;
|
||||
},
|
||||
|
||||
|
@ -147,21 +156,32 @@ var HTML5AudioSoundManager = new Class({
|
|||
unlock: function ()
|
||||
{
|
||||
var _this = this;
|
||||
|
||||
var moved = false;
|
||||
|
||||
var detectMove = function ()
|
||||
{
|
||||
moved = true;
|
||||
};
|
||||
|
||||
var unlock = function ()
|
||||
{
|
||||
if (!_this.game.cache.audio.entries.size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (moved)
|
||||
{
|
||||
moved = false;
|
||||
return;
|
||||
}
|
||||
|
||||
document.body.removeEventListener('touchmove', detectMove);
|
||||
document.body.removeEventListener('touchend', unlock);
|
||||
|
||||
var allTags = [];
|
||||
|
||||
_this.game.cache.audio.entries.each(function (key, tags)
|
||||
{
|
||||
for (var i = 0; i < tags.length; i++)
|
||||
|
@ -170,25 +190,30 @@ var HTML5AudioSoundManager = new Class({
|
|||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
var lastTag = allTags[allTags.length - 1];
|
||||
|
||||
lastTag.oncanplaythrough = function ()
|
||||
{
|
||||
lastTag.oncanplaythrough = null;
|
||||
_this.unlocked = true;
|
||||
};
|
||||
|
||||
allTags.forEach(function (tag)
|
||||
{
|
||||
tag.load();
|
||||
});
|
||||
};
|
||||
|
||||
this.once('unlocked', function ()
|
||||
{
|
||||
_this.forEachActiveSound(function (sound)
|
||||
this.forEachActiveSound(function (sound)
|
||||
{
|
||||
sound.duration = sound.tags[0].duration;
|
||||
sound.totalDuration = sound.tags[0].duration;
|
||||
});
|
||||
_this.lockedActionsQueue.forEach(function (lockedAction)
|
||||
|
||||
this.lockedActionsQueue.forEach(function (lockedAction)
|
||||
{
|
||||
if (lockedAction.sound[lockedAction.prop].apply)
|
||||
{
|
||||
|
@ -199,9 +224,11 @@ var HTML5AudioSoundManager = new Class({
|
|||
lockedAction.sound[lockedAction.prop] = lockedAction.value;
|
||||
}
|
||||
});
|
||||
_this.lockedActionsQueue.length = 0;
|
||||
_this.lockedActionsQueue = null;
|
||||
});
|
||||
|
||||
this.lockedActionsQueue.length = 0;
|
||||
this.lockedActionsQueue = null;
|
||||
}, this);
|
||||
|
||||
document.body.addEventListener('touchmove', detectMove, false);
|
||||
document.body.addEventListener('touchend', unlock, false);
|
||||
},
|
||||
|
@ -240,6 +267,7 @@ var HTML5AudioSoundManager = new Class({
|
|||
{
|
||||
sound.onFocus();
|
||||
});
|
||||
|
||||
this.onBlurPausedSounds.length = 0;
|
||||
},
|
||||
|
||||
|
@ -253,6 +281,7 @@ var HTML5AudioSoundManager = new Class({
|
|||
destroy: function ()
|
||||
{
|
||||
BaseSoundManager.prototype.destroy.call(this);
|
||||
|
||||
this.onBlurPausedSounds.length = 0;
|
||||
this.onBlurPausedSounds = null;
|
||||
},
|
||||
|
@ -281,51 +310,79 @@ var HTML5AudioSoundManager = new Class({
|
|||
prop: prop,
|
||||
value: value
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(HTML5AudioSoundManager.prototype, 'mute', {
|
||||
get: function ()
|
||||
{
|
||||
return this._mute;
|
||||
},
|
||||
set: function (value)
|
||||
{
|
||||
this._mute = value;
|
||||
this.forEachActiveSound(function (sound)
|
||||
{
|
||||
sound.setMute();
|
||||
});
|
||||
|
||||
/**
|
||||
* @event Phaser.Sound.HTML5AudioSoundManager#mute
|
||||
* @param {Phaser.Sound.HTML5AudioSoundManager} soundManager - Reference to the sound manager that emitted event.
|
||||
* @param {boolean} value - An updated value of Phaser.Sound.HTML5AudioSoundManager#mute property.
|
||||
*/
|
||||
this.emit('mute', this, value);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(HTML5AudioSoundManager.prototype, 'volume', {
|
||||
get: function ()
|
||||
{
|
||||
return this._volume;
|
||||
/**
|
||||
* @event Phaser.Sound.HTML5AudioSoundManager#MuteEvent
|
||||
* @param {Phaser.Sound.HTML5AudioSoundManager} soundManager - Reference to the sound manager that emitted event.
|
||||
* @param {boolean} value - An updated value of Phaser.Sound.HTML5AudioSoundManager#mute property.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name Phaser.Sound.HTML5AudioSoundManager#mute
|
||||
* @type {boolean}
|
||||
* @fires Phaser.Sound.HTML5AudioSoundManager#MuteEvent
|
||||
* @since 3.0.0
|
||||
*/
|
||||
mute: {
|
||||
|
||||
get: function ()
|
||||
{
|
||||
return this._mute;
|
||||
},
|
||||
|
||||
set: function (value)
|
||||
{
|
||||
this._mute = value;
|
||||
|
||||
this.forEachActiveSound(function (sound)
|
||||
{
|
||||
sound.setMute();
|
||||
});
|
||||
|
||||
this.emit('mute', this, value);
|
||||
}
|
||||
|
||||
},
|
||||
set: function (value)
|
||||
{
|
||||
this._volume = value;
|
||||
this.forEachActiveSound(function (sound)
|
||||
{
|
||||
sound.setVolume();
|
||||
});
|
||||
|
||||
/**
|
||||
* @event Phaser.Sound.HTML5AudioSoundManager#volume
|
||||
* @param {Phaser.Sound.HTML5AudioSoundManager} soundManager - Reference to the sound manager that emitted event.
|
||||
* @param {number} value - An updated value of Phaser.Sound.HTML5AudioSoundManager#volume property.
|
||||
*/
|
||||
this.emit('volume', this, value);
|
||||
/**
|
||||
* @event Phaser.Sound.HTML5AudioSoundManager#VolumeEvent
|
||||
* @param {Phaser.Sound.HTML5AudioSoundManager} soundManager - Reference to the sound manager that emitted event.
|
||||
* @param {number} value - An updated value of Phaser.Sound.HTML5AudioSoundManager#volume property.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name Phaser.Sound.HTML5AudioSoundManager#volume
|
||||
* @type {number}
|
||||
* @fires Phaser.Sound.HTML5AudioSoundManager#VolumeEvent
|
||||
* @since 3.0.0
|
||||
*/
|
||||
volume: {
|
||||
|
||||
get: function ()
|
||||
{
|
||||
return this._volume;
|
||||
},
|
||||
|
||||
set: function (value)
|
||||
{
|
||||
this._volume = value;
|
||||
|
||||
this.forEachActiveSound(function (sound)
|
||||
{
|
||||
sound.setVolume();
|
||||
});
|
||||
|
||||
this.emit('volume', this, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = HTML5AudioSoundManager;
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
var Class = require('../../utils/Class');
|
||||
|
||||
var BaseSoundManager = require('../BaseSoundManager');
|
||||
var Class = require('../../utils/Class');
|
||||
var WebAudioSound = require('./WebAudioSound');
|
||||
|
||||
/**
|
||||
|
@ -21,8 +22,12 @@ var WebAudioSound = require('./WebAudioSound');
|
|||
* @param {Phaser.Game} game - Reference to the current game instance.
|
||||
*/
|
||||
var WebAudioSoundManager = new Class({
|
||||
|
||||
Extends: BaseSoundManager,
|
||||
initialize: function WebAudioSoundManager (game)
|
||||
|
||||
initialize:
|
||||
|
||||
function WebAudioSoundManager (game)
|
||||
{
|
||||
/**
|
||||
* The AudioContext being used for playback.
|
||||
|
@ -53,7 +58,9 @@ var WebAudioSoundManager = new Class({
|
|||
* @since 3.0.0
|
||||
*/
|
||||
this.masterVolumeNode = this.context.createGain();
|
||||
|
||||
this.masterMuteNode.connect(this.masterVolumeNode);
|
||||
|
||||
this.masterVolumeNode.connect(this.context.destination);
|
||||
|
||||
/**
|
||||
|
@ -65,7 +72,9 @@ var WebAudioSoundManager = new Class({
|
|||
* @since 3.0.0
|
||||
*/
|
||||
this.destination = this.masterMuteNode;
|
||||
|
||||
this.locked = this.context.state === 'suspended' && 'ontouchstart' in window;
|
||||
|
||||
BaseSoundManager.call(this, game);
|
||||
},
|
||||
|
||||
|
@ -87,11 +96,13 @@ var WebAudioSoundManager = new Class({
|
|||
createAudioContext: function (game)
|
||||
{
|
||||
var audioConfig = game.config.audio;
|
||||
|
||||
if (audioConfig && audioConfig.context)
|
||||
{
|
||||
audioConfig.context.resume();
|
||||
return audioConfig.context;
|
||||
}
|
||||
|
||||
return new AudioContext();
|
||||
},
|
||||
|
||||
|
@ -108,8 +119,11 @@ var WebAudioSoundManager = new Class({
|
|||
*/
|
||||
add: function (key, config)
|
||||
{
|
||||
|
||||
var sound = new WebAudioSound(this, key, config);
|
||||
|
||||
this.sounds.push(sound);
|
||||
|
||||
return sound;
|
||||
},
|
||||
|
||||
|
@ -125,6 +139,7 @@ var WebAudioSoundManager = new Class({
|
|||
unlock: function ()
|
||||
{
|
||||
var _this = this;
|
||||
|
||||
var unlock = function ()
|
||||
{
|
||||
_this.context.resume().then(function ()
|
||||
|
@ -134,6 +149,7 @@ var WebAudioSoundManager = new Class({
|
|||
_this.unlocked = true;
|
||||
});
|
||||
};
|
||||
|
||||
document.body.addEventListener('touchstart', unlock, false);
|
||||
document.body.addEventListener('touchend', unlock, false);
|
||||
},
|
||||
|
@ -178,6 +194,7 @@ var WebAudioSoundManager = new Class({
|
|||
this.masterVolumeNode = null;
|
||||
this.masterMuteNode.disconnect();
|
||||
this.masterMuteNode = null;
|
||||
|
||||
if (this.game.config.audio && this.game.config.audio.context)
|
||||
{
|
||||
this.context.suspend();
|
||||
|
@ -186,42 +203,68 @@ var WebAudioSoundManager = new Class({
|
|||
{
|
||||
this.context.close();
|
||||
}
|
||||
|
||||
this.context = null;
|
||||
|
||||
BaseSoundManager.prototype.destroy.call(this);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(WebAudioSoundManager.prototype, 'mute', {
|
||||
get: function ()
|
||||
{
|
||||
return this.masterMuteNode.gain.value === 0;
|
||||
},
|
||||
set: function (value)
|
||||
{
|
||||
this.masterMuteNode.gain.setValueAtTime(value ? 0 : 1, 0);
|
||||
|
||||
/**
|
||||
* @event Phaser.Sound.WebAudioSoundManager#mute
|
||||
* @param {Phaser.Sound.WebAudioSoundManager} soundManager - Reference to the sound manager that emitted event.
|
||||
* @param {boolean} value - An updated value of Phaser.Sound.WebAudioSoundManager#mute property.
|
||||
*/
|
||||
this.emit('mute', this, value);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(WebAudioSoundManager.prototype, 'volume', {
|
||||
get: function ()
|
||||
{
|
||||
return this.masterVolumeNode.gain.value;
|
||||
/**
|
||||
* @event Phaser.Sound.WebAudioSoundManager#MuteEvent
|
||||
* @param {Phaser.Sound.WebAudioSoundManager} soundManager - Reference to the sound manager that emitted event.
|
||||
* @param {boolean} value - An updated value of Phaser.Sound.WebAudioSoundManager#mute property.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name Phaser.Sound.WebAudioSoundManager#mute
|
||||
* @type {boolean}
|
||||
* @fires Phaser.Sound.WebAudioSoundManager#MuteEvent
|
||||
* @since 3.0.0
|
||||
*/
|
||||
mute: {
|
||||
|
||||
get: function ()
|
||||
{
|
||||
return (this.masterMuteNode.gain.value === 0);
|
||||
},
|
||||
|
||||
set: function (value)
|
||||
{
|
||||
this.masterMuteNode.gain.setValueAtTime(value ? 0 : 1, 0);
|
||||
|
||||
this.emit('mute', this, value);
|
||||
}
|
||||
|
||||
},
|
||||
set: function (value)
|
||||
{
|
||||
this.masterVolumeNode.gain.setValueAtTime(value, 0);
|
||||
|
||||
/**
|
||||
* @event Phaser.Sound.WebAudioSoundManager#volume
|
||||
* @param {Phaser.Sound.WebAudioSoundManager} soundManager - Reference to the sound manager that emitted event.
|
||||
* @param {number} value - An updated value of Phaser.Sound.WebAudioSoundManager#volume property.
|
||||
*/
|
||||
this.emit('volume', this, value);
|
||||
/**
|
||||
* @event Phaser.Sound.WebAudioSoundManager#VolumeEvent
|
||||
* @param {Phaser.Sound.WebAudioSoundManager} soundManager - Reference to the sound manager that emitted event.
|
||||
* @param {number} value - An updated value of Phaser.Sound.WebAudioSoundManager#volume property.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name Phaser.Sound.WebAudioSoundManager#volume
|
||||
* @type {number}
|
||||
* @fires Phaser.Sound.WebAudioSoundManager#VolumeEvent
|
||||
* @since 3.0.0
|
||||
*/
|
||||
volume: {
|
||||
|
||||
get: function ()
|
||||
{
|
||||
return this.masterVolumeNode.gain.value;
|
||||
},
|
||||
|
||||
set: function (value)
|
||||
{
|
||||
this.masterVolumeNode.gain.setValueAtTime(value, 0);
|
||||
|
||||
this.emit('volume', this, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = WebAudioSoundManager;
|
||||
|
|
Loading…
Reference in a new issue