mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2025-08-28 22:30:40 -04:00
Merge pull request #1632 from mzgoddard/stop-other-sounds
Stop other sounds
This commit is contained in:
commit
5e5655c916
3 changed files with 53 additions and 7 deletions
|
@ -2,6 +2,12 @@ const MathUtil = require('../util/math-util');
|
||||||
const Cast = require('../util/cast');
|
const Cast = require('../util/cast');
|
||||||
const Clone = require('../util/clone');
|
const Clone = require('../util/clone');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Occluded boolean value to make its use more understandable.
|
||||||
|
* @const {boolean}
|
||||||
|
*/
|
||||||
|
const STORE_WAITING = true;
|
||||||
|
|
||||||
class Scratch3SoundBlocks {
|
class Scratch3SoundBlocks {
|
||||||
constructor (runtime) {
|
constructor (runtime) {
|
||||||
/**
|
/**
|
||||||
|
@ -10,10 +16,16 @@ class Scratch3SoundBlocks {
|
||||||
*/
|
*/
|
||||||
this.runtime = runtime;
|
this.runtime = runtime;
|
||||||
|
|
||||||
|
this.waitingSounds = {};
|
||||||
|
|
||||||
// Clear sound effects on green flag and stop button events.
|
// Clear sound effects on green flag and stop button events.
|
||||||
|
this.stopAllSounds = this.stopAllSounds.bind(this);
|
||||||
|
this._stopWaitingSoundsForTarget = this._stopWaitingSoundsForTarget.bind(this);
|
||||||
this._clearEffectsForAllTargets = this._clearEffectsForAllTargets.bind(this);
|
this._clearEffectsForAllTargets = this._clearEffectsForAllTargets.bind(this);
|
||||||
if (this.runtime) {
|
if (this.runtime) {
|
||||||
|
this.runtime.on('PROJECT_STOP_ALL', this.stopAllSounds);
|
||||||
this.runtime.on('PROJECT_STOP_ALL', this._clearEffectsForAllTargets);
|
this.runtime.on('PROJECT_STOP_ALL', this._clearEffectsForAllTargets);
|
||||||
|
this.runtime.on('STOP_FOR_TARGET', this._stopWaitingSoundsForTarget);
|
||||||
this.runtime.on('PROJECT_START', this._clearEffectsForAllTargets);
|
this.runtime.on('PROJECT_START', this._clearEffectsForAllTargets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,21 +153,44 @@ class Scratch3SoundBlocks {
|
||||||
|
|
||||||
playSound (args, util) {
|
playSound (args, util) {
|
||||||
// Don't return the promise, it's the only difference for AndWait
|
// Don't return the promise, it's the only difference for AndWait
|
||||||
this.playSoundAndWait(args, util);
|
this._playSound(args, util);
|
||||||
}
|
}
|
||||||
|
|
||||||
playSoundAndWait (args, util) {
|
playSoundAndWait (args, util) {
|
||||||
|
return this._playSound(args, util, STORE_WAITING);
|
||||||
|
}
|
||||||
|
|
||||||
|
_playSound (args, util, storeWaiting) {
|
||||||
const index = this._getSoundIndex(args.SOUND_MENU, util);
|
const index = this._getSoundIndex(args.SOUND_MENU, util);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
const {target} = util;
|
const {target} = util;
|
||||||
const {sprite} = target;
|
const {sprite} = target;
|
||||||
const {soundId} = sprite.sounds[index];
|
const {soundId} = sprite.sounds[index];
|
||||||
if (sprite.soundBank) {
|
if (sprite.soundBank) {
|
||||||
|
if (storeWaiting === STORE_WAITING) {
|
||||||
|
this._addWaitingSound(target.id, soundId);
|
||||||
|
} else {
|
||||||
|
this._removeWaitingSound(target.id, soundId);
|
||||||
|
}
|
||||||
return sprite.soundBank.playSound(target, soundId);
|
return sprite.soundBank.playSound(target, soundId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_addWaitingSound (targetId, soundId) {
|
||||||
|
if (!this.waitingSounds[targetId]) {
|
||||||
|
this.waitingSounds[targetId] = new Set();
|
||||||
|
}
|
||||||
|
this.waitingSounds[targetId].add(soundId);
|
||||||
|
}
|
||||||
|
|
||||||
|
_removeWaitingSound (targetId, soundId) {
|
||||||
|
if (!this.waitingSounds[targetId]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.waitingSounds[targetId].delete(soundId);
|
||||||
|
}
|
||||||
|
|
||||||
_getSoundIndex (soundName, util) {
|
_getSoundIndex (soundName, util) {
|
||||||
// if the sprite has no sounds, return -1
|
// if the sprite has no sounds, return -1
|
||||||
const len = util.target.sprite.sounds.length;
|
const len = util.target.sprite.sounds.length;
|
||||||
|
@ -201,6 +236,20 @@ class Scratch3SoundBlocks {
|
||||||
_stopAllSoundsForTarget (target) {
|
_stopAllSoundsForTarget (target) {
|
||||||
if (target.sprite.soundBank) {
|
if (target.sprite.soundBank) {
|
||||||
target.sprite.soundBank.stopAllSounds(target);
|
target.sprite.soundBank.stopAllSounds(target);
|
||||||
|
if (this.waitingSounds[target.id]) {
|
||||||
|
this.waitingSounds[target.id].clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_stopWaitingSoundsForTarget (target) {
|
||||||
|
if (target.sprite.soundBank) {
|
||||||
|
if (this.waitingSounds[target.id]) {
|
||||||
|
for (const soundId of this.waitingSounds[target.id].values()) {
|
||||||
|
target.sprite.soundBank.stop(target, soundId);
|
||||||
|
}
|
||||||
|
this.waitingSounds[target.id].clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1074,9 +1074,6 @@ class RenderedTarget extends Target {
|
||||||
*/
|
*/
|
||||||
onStopAll () {
|
onStopAll () {
|
||||||
this.clearEffects();
|
this.clearEffects();
|
||||||
if (this.sprite.soundBank) {
|
|
||||||
this.sprite.soundBank.stopAllSounds();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -67,7 +67,7 @@ test('ask and stop all dismisses question', t => {
|
||||||
test('ask and stop other scripts dismisses if it is the last question', t => {
|
test('ask and stop other scripts dismisses if it is the last question', t => {
|
||||||
const rt = new Runtime();
|
const rt = new Runtime();
|
||||||
const s = new Sensing(rt);
|
const s = new Sensing(rt);
|
||||||
const util = {target: {visible: false}, thread: {}};
|
const util = {target: {visible: false, sprite: {}}, thread: {}};
|
||||||
|
|
||||||
const expectedQuestion = 'a question';
|
const expectedQuestion = 'a question';
|
||||||
|
|
||||||
|
@ -94,8 +94,8 @@ test('ask and stop other scripts dismisses if it is the last question', t => {
|
||||||
test('ask and stop other scripts asks next question', t => {
|
test('ask and stop other scripts asks next question', t => {
|
||||||
const rt = new Runtime();
|
const rt = new Runtime();
|
||||||
const s = new Sensing(rt);
|
const s = new Sensing(rt);
|
||||||
const util = {target: {visible: false}, thread: {}};
|
const util = {target: {visible: false, sprite: {}}, thread: {}};
|
||||||
const util2 = {target: {visible: false}, thread: {}};
|
const util2 = {target: {visible: false, sprite: {}}, thread: {}};
|
||||||
|
|
||||||
const expectedQuestion = 'a question';
|
const expectedQuestion = 'a question';
|
||||||
const nextQuestion = 'a followup';
|
const nextQuestion = 'a followup';
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue