summaryrefslogtreecommitdiff
path: root/objects.js
diff options
context:
space:
mode:
Diffstat (limited to 'objects.js')
-rw-r--r--objects.js179
1 files changed, 164 insertions, 15 deletions
diff --git a/objects.js b/objects.js
index cb9ad4b..cf4d0ea 100644
--- a/objects.js
+++ b/objects.js
@@ -464,6 +464,23 @@ SpriteMorph.prototype.initBlocks = function () {
category: 'sound',
spec: 'stop all sounds'
},
+ doSetVolume: {
+ type: 'command',
+ category: 'sound',
+ spec: 'set volume to %n %',
+ defaults: [100]
+ },
+ doChangeVolume: {
+ type: 'command',
+ category: 'sound',
+ spec: 'change volume by %n',
+ defaults: [-10]
+ },
+ reportVolume: {
+ type: 'reporter',
+ category: 'sound',
+ spec: 'volume'
+ },
doRest: {
type: 'command',
category: 'sound',
@@ -868,6 +885,11 @@ SpriteMorph.prototype.initBlocks = function () {
category: 'sensing',
spec: 'key %key pressed?'
},
+ getKeysPressed: {
+ type: 'reporter',
+ category: 'sensing',
+ spec: 'keys pressed'
+ },
reportDistanceTo: {
type: 'reporter',
category: 'sensing',
@@ -1376,6 +1398,8 @@ SpriteMorph.prototype.init = function (globals) {
this.version = Date.now(); // for observer optimization
this.isClone = false; // indicate a "temporary" Scratch-style clone
this.cloneOriginName = '';
+ this.volume = 100;
+ this.activeSounds = [];
// sprite nesting properties
this.parts = []; // not serialized, only anchor (name)
@@ -1479,8 +1503,11 @@ SpriteMorph.prototype.appearIn = function (ide) {
// SpriteMorph versioning
SpriteMorph.prototype.setName = function (string) {
- this.name = string || this.name;
- this.version = Date.now();
+ if (string != 'mouse-pointer' && string != 'pen trails'
+ && string != 'edge') { // used by system
+ this.name = string || this.name;
+ this.version = Date.now();
+ }
};
// SpriteMorph rendering
@@ -1852,6 +1879,11 @@ SpriteMorph.prototype.blockTemplates = function (category) {
blocks.push(block('doPlaySoundUntilDone'));
blocks.push(block('doStopAllSounds'));
blocks.push('-');
+ blocks.push(block('doSetVolume'));
+ blocks.push(block('doChangeVolume'));
+ blocks.push(watcherToggle('reportVolume'));
+ blocks.push(block('reportVolume'));
+ blocks.push('-');
blocks.push(block('doRest'));
blocks.push('-');
blocks.push(block('doPlayNote'));
@@ -1970,6 +2002,7 @@ SpriteMorph.prototype.blockTemplates = function (category) {
blocks.push(block('reportMouseDown'));
blocks.push('-');
blocks.push(block('reportKeyPressed'));
+ blocks.push(block('getKeysPressed'));
blocks.push('-');
blocks.push(block('reportDistanceTo'));
blocks.push('-');
@@ -2688,7 +2721,8 @@ SpriteMorph.prototype.reportCostumes = function () {
// SpriteMorph sound management
SpriteMorph.prototype.addSound = function (audio, name) {
- this.sounds.add(new Sound(audio, name));
+ var volume = this.volume;
+ this.sounds.add(new Sound(audio, name, volume));
};
SpriteMorph.prototype.playSound = function (name) {
@@ -2699,7 +2733,18 @@ SpriteMorph.prototype.playSound = function (name) {
),
active;
if (sound) {
+ sound.volume = this.volume;
active = sound.play();
+
+ if (stage.muted === true) {
+ active.volume = 0;
+ }
+
+ this.activeSounds.push(active);
+ this.activeSounds = this.activeSounds.filter(function (aud) {
+ return !aud.ended && !aud.terminated;
+ });
+
if (stage) {
stage.activeSounds.push(active);
stage.activeSounds = stage.activeSounds.filter(function (aud) {
@@ -2710,6 +2755,34 @@ SpriteMorph.prototype.playSound = function (name) {
}
};
+SpriteMorph.prototype.doSetVolume = function (val) {
+ var myself = this;
+ myself.volume = Math.min(Math.max(0, val), 100);
+
+ if (myself.parentThatIsA(StageMorph).muted === true) {
+ return;
+ }
+
+ myself.activeSounds.forEach(function (snd) {
+ snd.volume = myself.volume / 100; // 'audio' objects
+ });
+};
+
+SpriteMorph.prototype.doChangeVolume = function (val) {
+ this.doSetVolume(this.volume + val);
+};
+
+SpriteMorph.prototype.reportVolume = function () {
+ return this.volume;
+}
+
+SpriteMorph.prototype.unmuteAllSounds = function () {
+ var stage = this.parentThatIsA(StageMorph);
+ stage.muted = false;
+
+ this.doSetVolume(this.volume);
+};
+
SpriteMorph.prototype.reportSounds = function () {
return this.sounds;
};
@@ -3361,9 +3434,7 @@ Morph.prototype.setPosition = function (aPoint, justMe) {
// override the inherited default to make sure my parts follow
// unless it's justMe
var delta = aPoint.subtract(this.topLeft());
- if ((delta.x !== 0) || (delta.y !== 0)) {
- this.moveBy(delta, justMe);
- }
+ this.moveBy(delta, justMe);
};
SpriteMorph.prototype.forward = function (steps) {
@@ -3596,7 +3667,19 @@ SpriteMorph.prototype.allHatBlocksForKey = function (key) {
return this.scripts.children.filter(function (morph) {
if (morph.selector) {
if (morph.selector === 'receiveKey') {
- return morph.inputs()[0].evaluate()[0] === key;
+ var selectedOption = morph.inputs()[0].evaluate()[0];
+
+ if (selectedOption === 'any key') {
+ return true;
+ }
+ if (selectedOption === 'number key' &&
+ (key >= '0' && key <= '9')) {
+ return true;
+ }
+ if (selectedOption === key) {
+ return true;
+ }
+ return false;
}
}
return false;
@@ -3641,6 +3724,16 @@ SpriteMorph.prototype.getTempo = function () {
return 0;
};
+// SpriteMorph last key
+
+SpriteMorph.prototype.getKeysPressed = function () {
+ var stage = this.parentThatIsA(StageMorph);
+ if (stage) {
+ return stage.getKeysPressed();
+ }
+ return '';
+};
+
// SpriteMorph last message
SpriteMorph.prototype.getLastMessage = function () {
@@ -4395,6 +4488,8 @@ StageMorph.prototype.init = function (globals) {
this.version = Date.now(); // for observers
this.isFastTracked = false;
this.cloneCount = 0;
+ this.volume = 100;
+ this.muted = false;
this.timerStart = Date.now();
this.tempo = 60; // bpm
@@ -4683,6 +4778,16 @@ StageMorph.prototype.getTempo = function () {
return +this.tempo;
};
+// StageMorph keys
+
+StageMorph.prototype.getKeysPressed = function () {
+ var keys = [];
+ for (var key in this.keysPressed) {
+ keys.push(key);
+ }
+ return new List(keys);
+};
+
// StageMorph messages
StageMorph.prototype.getLastMessage = function () {
@@ -4736,7 +4841,7 @@ StageMorph.prototype.step = function () {
world.keyboardReceiver = this;
}
if (world.currentKey === null) {
- this.keyPressed = null;
+ this.keysPressed = {};
}
// manage threads
@@ -4924,7 +5029,7 @@ StageMorph.prototype.fireGreenFlagEvent = function () {
StageMorph.prototype.fireStopAllEvent = function () {
var ide = this.parentThatIsA(IDE_Morph);
- this.threads.resumeAll(this.stage);
+ //this.threads.resumeAll(this.stage); // leads to a strange Note bug
this.keysPressed = {};
this.threads.stopAll();
this.stopAllActiveSounds();
@@ -5080,6 +5185,11 @@ StageMorph.prototype.blockTemplates = function (category) {
blocks.push(block('doPlaySoundUntilDone'));
blocks.push(block('doStopAllSounds'));
blocks.push('-');
+ blocks.push(block('doSetVolume'));
+ blocks.push(block('doChangeVolume'));
+ blocks.push(watcherToggle('reportVolume'));
+ blocks.push(block('reportVolume'));
+ blocks.push('-');
blocks.push(block('doRest'));
blocks.push('-');
blocks.push(block('doPlayNote'));
@@ -5178,6 +5288,7 @@ StageMorph.prototype.blockTemplates = function (category) {
blocks.push(block('reportMouseDown'));
blocks.push('-');
blocks.push(block('reportKeyPressed'));
+ blocks.push(block('getKeysPressed'));
blocks.push('-');
blocks.push(block('doResetTimer'));
blocks.push(watcherToggle('getTimer'));
@@ -5631,6 +5742,15 @@ StageMorph.prototype.addSound
StageMorph.prototype.playSound
= SpriteMorph.prototype.playSound;
+StageMorph.prototype.doSetVolume
+ = SpriteMorph.prototype.doSetVolume;
+
+StageMorph.prototype.doChangeVolume
+ = SpriteMorph.prototype.doChangeVolume;
+
+StageMorph.prototype.reportVolume
+ = SpriteMorph.prototype.reportVolume;
+
StageMorph.prototype.stopAllActiveSounds = function () {
this.activeSounds.forEach(function (audio) {
audio.pause();
@@ -5645,11 +5765,29 @@ StageMorph.prototype.pauseAllActiveSounds = function () {
};
StageMorph.prototype.resumeAllActiveSounds = function () {
+ var newSounds = []; // remove Sounds that have been played so they do not resume
+
this.activeSounds.forEach(function (audio) {
- audio.play();
+ if (audio.ended === false) {
+ newSounds.push(audio);
+ audio.play();
+ }
});
+
+ this.activeSounds = newSounds;
};
+StageMorph.prototype.muteAllSounds = function () {
+ this.muted = true;
+
+ this.activeSounds.forEach(function (audio) {
+ audio.volume = 0;
+ });
+};
+
+StageMorph.prototype.unmuteAllSounds
+ = SpriteMorph.prototype.unmuteAllSounds;
+
StageMorph.prototype.reportSounds
= SpriteMorph.prototype.reportSounds;
@@ -6403,9 +6541,10 @@ CostumeEditorMorph.prototype.mouseMove
// Sound instance creation
-function Sound(audio, name) {
+function Sound(audio, name, volume) {
this.audio = audio; // mandatory
this.name = name || "Sound";
+ this.volume = volume || 100;
}
Sound.prototype.play = function () {
@@ -6413,6 +6552,7 @@ Sound.prototype.play = function () {
// externally (i.e. by the stage)
var aud = document.createElement('audio');
aud.src = this.audio.src;
+ aud.volume = Math.min(Math.max(0, this.volume), 100) / 100;
aud.play();
return aud;
};
@@ -6422,7 +6562,8 @@ Sound.prototype.copy = function () {
cpy;
snd.src = this.audio.src;
- cpy = new Sound(snd, this.name ? copy(this.name) : null);
+ snd.volume = this.volume;
+ cpy = new Sound(snd, this.name ? copy(this.name) : null, this.volume ? copy(this.volume) : null);
return cpy;
};
@@ -6436,8 +6577,9 @@ Sound.prototype.toDataURL = function () {
// Note instance creation
-function Note(pitch) {
+function Note(pitch, volume) {
this.pitch = pitch === 0 ? 0 : pitch || 69;
+ this.volume = volume;
this.setupContext();
this.oscillator = null;
}
@@ -6468,12 +6610,13 @@ Note.prototype.setupContext = function () {
}
Note.prototype.audioContext = new AudioContext();
Note.prototype.gainNode = Note.prototype.audioContext.createGain();
- Note.prototype.gainNode.gain.value = 0.25; // reduce volume by 1/4
};
// Note playing
Note.prototype.play = function () {
+ this.gainNode.gain.value = 0.25 * this.volume / 100; // reduce volume by 1/4
+
this.oscillator = this.audioContext.createOscillator();
if (!this.oscillator.start) {
this.oscillator.start = this.oscillator.noteOn;
@@ -6489,6 +6632,12 @@ Note.prototype.play = function () {
this.oscillator.start(0);
};
+Note.prototype.setVolume = function (volume) {
+ this.stop();
+ this.volume = volume;
+ this.play();
+}
+
Note.prototype.stop = function () {
if (this.oscillator) {
this.oscillator.stop(0);
@@ -6917,7 +7066,7 @@ WatcherMorph.prototype.object = function () {
WatcherMorph.prototype.isGlobal = function (selector) {
return contains(
- ['getLastAnswer', 'getLastMessage', 'getTempo', 'getTimer',
+ ['getLastAnswer', 'getKeysPressed', 'getLastMessage', 'getTempo', 'getTimer',
'reportMouseX', 'reportMouseY', 'reportThreadCount'],
selector
);