Merge pull request #891 from ericrosenbaum/bugfix/audioplayer-clone-state

Audio effects state for clones
This commit is contained in:
Eric Rosenbaum 2018-01-23 11:55:39 -05:00 committed by GitHub
commit 115184a2a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 8 deletions

View file

@ -16,6 +16,11 @@ class Scratch3SoundBlocks {
this.runtime.on('PROJECT_STOP_ALL', this._clearEffectsForAllTargets); this.runtime.on('PROJECT_STOP_ALL', this._clearEffectsForAllTargets);
this.runtime.on('PROJECT_START', this._clearEffectsForAllTargets); this.runtime.on('PROJECT_START', this._clearEffectsForAllTargets);
} }
this._onTargetCreated = this._onTargetCreated.bind(this);
if (this.runtime) {
runtime.on('targetWasCreated', this._onTargetCreated);
}
} }
/** /**
@ -88,6 +93,23 @@ class Scratch3SoundBlocks {
return soundState; return soundState;
} }
/**
* When a Target is cloned, clone the sound state.
* @param {Target} newTarget - the newly created target.
* @param {Target} [sourceTarget] - the target used as a source for the new clone, if any.
* @listens Runtime#event:targetWasCreated
* @private
*/
_onTargetCreated (newTarget, sourceTarget) {
if (sourceTarget) {
const soundState = sourceTarget.getCustomState(Scratch3SoundBlocks.STATE_KEY);
if (soundState && newTarget) {
newTarget.setCustomState(Scratch3SoundBlocks.STATE_KEY, Clone.simple(soundState));
this._syncEffectsForTarget(newTarget);
}
}
}
/** /**
* Retrieve the block primitives implemented by this package. * Retrieve the block primitives implemented by this package.
* @return {object.<string, Function>} Mapping of opcode to Function. * @return {object.<string, Function>} Mapping of opcode to Function.
@ -208,6 +230,15 @@ class Scratch3SoundBlocks {
util.target.audioPlayer.setEffect(effect, soundState.effects[effect]); util.target.audioPlayer.setEffect(effect, soundState.effects[effect]);
} }
_syncEffectsForTarget (target) {
if (!target || !target.audioPlayer) return;
const soundState = this._getSoundState(target);
for (const effect in soundState.effects) {
if (!soundState.effects.hasOwnProperty(effect)) continue;
target.audioPlayer.setEffect(effect, soundState.effects[effect]);
}
}
clearEffects (args, util) { clearEffects (args, util) {
this._clearEffectsForTarget(util.target); this._clearEffectsForTarget(util.target);
} }

View file

@ -131,17 +131,15 @@ class RenderedTarget extends Target {
'control_start_as_clone', null, this 'control_start_as_clone', null, this
); );
} }
}
/** /**
* Audio player * Initialize the audio player for this sprite or clone.
*/ */
initAudio () {
this.audioPlayer = null; this.audioPlayer = null;
if (this.runtime && this.runtime.audioEngine) { if (this.runtime && this.runtime.audioEngine) {
if (this.isOriginal) {
this.audioPlayer = this.runtime.audioEngine.createPlayer(); this.audioPlayer = this.runtime.audioEngine.createPlayer();
} else {
this.audioPlayer = this.sprite.clones[0].audioPlayer;
}
} }
} }
@ -940,6 +938,10 @@ class RenderedTarget extends Target {
this.runtime.requestRedraw(); this.runtime.requestRedraw();
} }
} }
if (this.audioPlayer) {
this.audioPlayer.stopAllSounds();
this.audioPlayer.dispose();
}
} }
} }

View file

@ -56,6 +56,7 @@ class Sprite {
const newClone = new RenderedTarget(this, this.runtime); const newClone = new RenderedTarget(this, this.runtime);
newClone.isOriginal = this.clones.length === 0; newClone.isOriginal = this.clones.length === 0;
this.clones.push(newClone); this.clones.push(newClone);
newClone.initAudio();
if (newClone.isOriginal) { if (newClone.isOriginal) {
newClone.initDrawable(); newClone.initDrawable();
this.runtime.fireTargetWasCreated(newClone); this.runtime.fireTargetWasCreated(newClone);