kopia lustrzana https://github.com/backface/turtlestitch
new feature: volume blocks
individual, persistent, non-inheritable, decibels-based volume attribute for sprites and the stagepull/89/head
rodzic
01b3c77aab
commit
b21fea7a32
|
@ -14,6 +14,7 @@
|
|||
* new "object" reporter in the Sensing category for getting a sprite by its name
|
||||
* blocks for changing and querying the "flat line ends" setting
|
||||
* selectors for changing and querying "draggable" and "rotation style" settings
|
||||
* new sound + music "volume" feature + blocks
|
||||
* added "neg" selector to monadic function reporter in "Operators" category
|
||||
* added "log2" selector to monadic function reporter in "Operators" category
|
||||
* added "^" reporter (power of) in the Operators category
|
||||
|
@ -56,6 +57,7 @@
|
|||
|
||||
### 2019-04-03
|
||||
* Objects: Threads: Safari compatibility tweaks (only use StereoPanner if available)
|
||||
* Objects. Store: new feature: volume blocks
|
||||
|
||||
### 2019-04-02
|
||||
* Objects, Threads: lazily initialize volume property
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<script type="text/javascript" src="src/symbols.js?version=2019-03-07"></script>
|
||||
<script type="text/javascript" src="src/sketch.js?version=2019-02-22"></script>
|
||||
<script type="text/javascript" src="src/xml.js?version=2018-11-12"></script>
|
||||
<script type="text/javascript" src="src/store.js?version=2019-02-22"></script>
|
||||
<script type="text/javascript" src="src/store.js?version=2019-04-03"></script>
|
||||
<script type="text/javascript" src="src/locale.js?version=2019-03-31"></script>
|
||||
<script type="text/javascript" src="src/cloud.js?version=2019-03-25"></script>
|
||||
<script type="text/javascript" src="src/sha512.js?version=2018-10-02"></script>
|
||||
|
|
|
@ -479,6 +479,23 @@ SpriteMorph.prototype.initBlocks = function () {
|
|||
category: 'sound',
|
||||
spec: 'tempo'
|
||||
},
|
||||
changeVolume: {
|
||||
type: 'command',
|
||||
category: 'sound',
|
||||
spec: 'change volume by %n',
|
||||
defaults: [10]
|
||||
},
|
||||
setVolume: {
|
||||
type: 'command',
|
||||
category: 'sound',
|
||||
spec: 'set volume to %n %',
|
||||
defaults: [100]
|
||||
},
|
||||
getVolume: {
|
||||
type: 'reporter',
|
||||
category: 'sound',
|
||||
spec: 'volume'
|
||||
},
|
||||
|
||||
// Sound - Debugging primitives for development mode
|
||||
reportSounds: {
|
||||
|
@ -1979,6 +1996,11 @@ SpriteMorph.prototype.blockTemplates = function (category) {
|
|||
blocks.push(block('doSetTempo'));
|
||||
blocks.push(watcherToggle('getTempo'));
|
||||
blocks.push(block('getTempo'));
|
||||
blocks.push('-');
|
||||
blocks.push(block('changeVolume'));
|
||||
blocks.push(block('setVolume'));
|
||||
blocks.push(watcherToggle('getVolume'));
|
||||
blocks.push(block('getVolume'));
|
||||
|
||||
// for debugging: ///////////////
|
||||
|
||||
|
@ -3276,13 +3298,21 @@ SpriteMorph.prototype.reportSounds = function () {
|
|||
// SpriteMorph volume
|
||||
|
||||
SpriteMorph.prototype.setVolume = function (num) {
|
||||
this.volume = Math.max(Math.min(+num, 100), 0);
|
||||
this.volume = Math.max(Math.min(+num || 0, 100), 0);
|
||||
this.getGainNode().gain.setValueAtTime(
|
||||
1 / Math.pow(10, Math.log2(100 / this.volume)),
|
||||
this.audioContext().currentTime
|
||||
);
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.changeVolume = function (delta) {
|
||||
this.setVolume(this.volume + (+delta || 0));
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.getVolume = function () {
|
||||
return this.volume;
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.getGainNode = function () {
|
||||
if (!this.gainNode) {
|
||||
this.gainNode = this.audioContext().createGain();
|
||||
|
@ -7323,6 +7353,11 @@ StageMorph.prototype.blockTemplates = function (category) {
|
|||
blocks.push(block('doSetTempo'));
|
||||
blocks.push(watcherToggle('getTempo'));
|
||||
blocks.push(block('getTempo'));
|
||||
blocks.push('-');
|
||||
blocks.push(block('changeVolume'));
|
||||
blocks.push(block('setVolume'));
|
||||
blocks.push(watcherToggle('getVolume'));
|
||||
blocks.push(block('getVolume'));
|
||||
|
||||
// for debugging: ///////////////
|
||||
|
||||
|
@ -7935,6 +7970,12 @@ StageMorph.prototype.reportSounds
|
|||
StageMorph.prototype.setVolume
|
||||
= SpriteMorph.prototype.setVolume;
|
||||
|
||||
StageMorph.prototype.changeVolume
|
||||
= SpriteMorph.prototype.changeVolume;
|
||||
|
||||
StageMorph.prototype.getVolume
|
||||
= SpriteMorph.prototype.getVolume;
|
||||
|
||||
StageMorph.prototype.getGainNode
|
||||
= SpriteMorph.prototype.getGainNode;
|
||||
|
||||
|
|
17
src/store.js
17
src/store.js
|
@ -61,7 +61,7 @@ normalizeCanvas, contains*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.store = '2019-February-22';
|
||||
modules.store = '2019-April-03';
|
||||
|
||||
|
||||
// XML_Serializer ///////////////////////////////////////////////////////
|
||||
|
@ -265,6 +265,7 @@ SnapSerializer.prototype.watcherLabels = {
|
|||
direction: 'direction',
|
||||
getScale: 'size',
|
||||
getTempo: 'tempo',
|
||||
getVolume: 'volume',
|
||||
getLastAnswer: 'answer',
|
||||
getLastMessage: 'message',
|
||||
getTimer: 'timer',
|
||||
|
@ -394,6 +395,10 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode, remixID) {
|
|||
project.stage.fps = 30;
|
||||
StageMorph.prototype.frameRate = 30;
|
||||
}
|
||||
if (model.stage.attributes.volume) {
|
||||
project.stage.volume = +model.stage.attributes.volume;
|
||||
}
|
||||
|
||||
model.pentrails = model.stage.childNamed('pentrails');
|
||||
if (model.pentrails) {
|
||||
project.pentrails = new Image();
|
||||
|
@ -681,6 +686,9 @@ SnapSerializer.prototype.loadSprites = function (xmlString, ide) {
|
|||
if (model.attributes.pen) {
|
||||
sprite.penPoint = model.attributes.pen;
|
||||
}
|
||||
if (model.attributes.volume) {
|
||||
sprite.volume = +model.attributes.volume;
|
||||
}
|
||||
project.stage.add(sprite);
|
||||
ide.sprites.add(sprite);
|
||||
sprite.scale = parseFloat(model.attributes.scale || '1');
|
||||
|
@ -1402,6 +1410,9 @@ SnapSerializer.prototype.loadValue = function (model, object) {
|
|||
if (model.attributes.pen) {
|
||||
v.penPoint = model.attributes.pen;
|
||||
}
|
||||
if (model.attributes.volume) {
|
||||
v.volume = +model.attributes.volume;
|
||||
}
|
||||
myself.project.stage.add(v);
|
||||
v.scale = parseFloat(model.attributes.scale || '1');
|
||||
v.rotationStyle = parseFloat(
|
||||
|
@ -1679,6 +1690,7 @@ StageMorph.prototype.toXML = function (serializer) {
|
|||
'<stage name="@" width="@" height="@" ' +
|
||||
'costume="@" color="@,@,@,@" tempo="@" threadsafe="@" ' +
|
||||
'%' +
|
||||
'volume="@" ' +
|
||||
'lines="@" ' +
|
||||
'ternary="@" ' +
|
||||
'codify="@" ' +
|
||||
|
@ -1715,6 +1727,7 @@ StageMorph.prototype.toXML = function (serializer) {
|
|||
this.isThreadSafe,
|
||||
this.instrument ?
|
||||
' instrument="' + parseInt(this.instrument) + '" ' : '',
|
||||
this.volume,
|
||||
SpriteMorph.prototype.useFlatLineEnds ? 'flat' : 'round',
|
||||
BooleanSlotMorph.prototype.isTernary,
|
||||
this.enableCodeMapping,
|
||||
|
@ -1752,6 +1765,7 @@ SpriteMorph.prototype.toXML = function (serializer) {
|
|||
'<sprite name="@" idx="@" x="@" y="@"' +
|
||||
' heading="@"' +
|
||||
' scale="@"' +
|
||||
' volume="@"' +
|
||||
' rotation="@"' +
|
||||
'%' +
|
||||
' draggable="@"' +
|
||||
|
@ -1772,6 +1786,7 @@ SpriteMorph.prototype.toXML = function (serializer) {
|
|||
this.yPosition(),
|
||||
this.heading,
|
||||
this.scale,
|
||||
this.volume,
|
||||
this.rotationStyle,
|
||||
this.instrument ?
|
||||
' instrument="' + parseInt(this.instrument) + '" ' : '',
|
||||
|
|
Ładowanie…
Reference in New Issue