Formatting and indentation fixes
This commit is contained in:
parent
73fdd4b7eb
commit
1a72b01b31
22 changed files with 690 additions and 691 deletions
|
@ -55,14 +55,16 @@ header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
|
|||
};
|
||||
|
||||
// Pass in the cloud token for the project
|
||||
if(window.getCloudToken)
|
||||
if (window.getCloudToken) {
|
||||
flashvars.cloud_token = encodeURIComponent(getCloudToken());
|
||||
}
|
||||
|
||||
var params = {
|
||||
allowscriptaccess: 'always',
|
||||
allowfullscreen: 'false',
|
||||
wmode: 'direct',
|
||||
menu: 'false'};
|
||||
menu: 'false'
|
||||
};
|
||||
|
||||
var flashPlayer = null;
|
||||
//var swf_url = "http://cdn.scratch.mit.edu/scratchr2/static/Scratch.swf";
|
||||
|
@ -71,7 +73,7 @@ header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
|
|||
"http://cdn.scratch.mit.edu/scratchr2/static/expressInstall.swf",
|
||||
flashvars, params, null, function(e) {
|
||||
$('#flashScratch').css('visibility', 'visible');
|
||||
if(e.success) flashPlayer = e.ref;
|
||||
if (e.success) flashPlayer = e.ref;
|
||||
});
|
||||
|
||||
$('#trigger_green_flag, #greenSlide').click(function() {
|
||||
|
@ -104,7 +106,6 @@ header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
|
|||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="info">Loading...</div>
|
||||
|
||||
<button id="trigger_green_flag">Green flag</button>
|
||||
|
|
26
js/IO.js
26
js/IO.js
|
@ -33,20 +33,18 @@ var IO = function() {
|
|||
this.asset_suffix = '/get/';
|
||||
this.soundbank_base = 'soundbank/';
|
||||
this.spriteLayerCount = 0;
|
||||
}
|
||||
};
|
||||
|
||||
IO.prototype.loadProject = function(project_id) {
|
||||
var runningIO = this;
|
||||
$.getJSON(this.project_base + project_id + this.project_suffix,
|
||||
function(data) {
|
||||
$.getJSON(this.project_base + project_id + this.project_suffix, function(data) {
|
||||
runningIO.data = data;
|
||||
runningIO.makeObjects();
|
||||
runningIO.loadThreads();
|
||||
runningIO.loadNotesDrums();
|
||||
runtime.loadStart(); // Try to run the project.
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
IO.prototype.soundRequest = function(sound, sprite) {
|
||||
var request = new XMLHttpRequest();
|
||||
|
@ -63,9 +61,9 @@ IO.prototype.soundRequest = function(sound, sprite) {
|
|||
data[i] = samples[i];
|
||||
}
|
||||
sprite.soundsLoaded++;
|
||||
}
|
||||
};
|
||||
request.send();
|
||||
}
|
||||
};
|
||||
|
||||
IO.prototype.loadNotesDrums = function() {
|
||||
var self = this;
|
||||
|
@ -81,10 +79,10 @@ IO.prototype.loadNotesDrums = function() {
|
|||
var soundBuffer = waveData.readBytes(2 * info.sampleCount);
|
||||
Instr.samples[name] = soundBuffer;
|
||||
Instr.wavsLoaded++;
|
||||
}
|
||||
};
|
||||
request.send();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
IO.prototype.makeObjects = function() {
|
||||
// Create the stage
|
||||
|
@ -96,7 +94,7 @@ IO.prototype.makeObjects = function() {
|
|||
// Create the sprites
|
||||
$.each(this.data.children, function(index, obj) {
|
||||
var newSprite;
|
||||
if(!obj.cmd) {
|
||||
if (!obj.cmd) {
|
||||
newSprite = new Sprite(obj);
|
||||
} else {
|
||||
newSprite = new Reporter(obj);
|
||||
|
@ -107,7 +105,7 @@ IO.prototype.makeObjects = function() {
|
|||
if (!obj.cmd)
|
||||
newSprite.loadSounds();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
IO.prototype.loadThreads = function() {
|
||||
var target = runtime.stage;
|
||||
|
@ -125,7 +123,7 @@ IO.prototype.loadThreads = function() {
|
|||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Returns the number sprite we are rendering
|
||||
// used for initial layering assignment
|
||||
|
@ -133,4 +131,4 @@ IO.prototype.getCount = function() {
|
|||
var rv = this.spriteLayerCount;
|
||||
this.spriteLayerCount++;
|
||||
return rv;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@ var Block = function(opAndArgs, optionalSubstack) {
|
|||
this.nextBlock = null;
|
||||
this.tmp = -1;
|
||||
interp.fixArgs(this);
|
||||
}
|
||||
};
|
||||
|
||||
var Thread = function(block, target) {
|
||||
this.nextBlock = block; // next block to run; null when thread is finished
|
||||
|
@ -40,7 +40,7 @@ var Thread = function(block, target) {
|
|||
this.tmp = null; // used for thread operations like Timer
|
||||
this.tmpObj = []; // used for Sprite operations like glide
|
||||
this.firstTime = true;
|
||||
}
|
||||
};
|
||||
|
||||
var Interpreter = function() {
|
||||
// Interpreter state
|
||||
|
@ -54,7 +54,7 @@ var Interpreter = function() {
|
|||
this.yield = false;
|
||||
this.doRedraw = false;
|
||||
this.opCount = 0; // used to benchmark the interpreter
|
||||
}
|
||||
};
|
||||
|
||||
// Utilities for building blocks and sequences of blocks
|
||||
Interpreter.prototype.fixArgs = function(b) {
|
||||
|
@ -66,7 +66,7 @@ Interpreter.prototype.fixArgs = function(b) {
|
|||
if (arg && arg.constructor == Array) {
|
||||
if ((arg.length > 0) && (arg[0].constructor == Array)) {
|
||||
// if first element arg is itself an array, then arg is a substack
|
||||
if(!b.substack) {
|
||||
if (!b.substack) {
|
||||
b.substack = this.makeBlockList(arg);
|
||||
} else {
|
||||
b.substack2 = this.makeBlockList(arg);
|
||||
|
@ -80,7 +80,7 @@ Interpreter.prototype.fixArgs = function(b) {
|
|||
}
|
||||
}
|
||||
b.args = newArgs;
|
||||
}
|
||||
};
|
||||
|
||||
Interpreter.prototype.makeBlockList = function(blockList) {
|
||||
var firstBlock = null, lastBlock = null;
|
||||
|
@ -91,7 +91,7 @@ Interpreter.prototype.makeBlockList = function(blockList) {
|
|||
lastBlock = b;
|
||||
}
|
||||
return firstBlock;
|
||||
}
|
||||
};
|
||||
|
||||
// The Interpreter proper
|
||||
Interpreter.prototype.stepThreads = function() {
|
||||
|
@ -121,11 +121,11 @@ Interpreter.prototype.stepThreads = function() {
|
|||
}
|
||||
this.currentMSecs = this.timer.time();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Interpreter.prototype.stepActiveThread = function() {
|
||||
// Run the active thread until it yields.
|
||||
if(typeof(this.activeThread) == 'undefined') {
|
||||
if (typeof(this.activeThread) == 'undefined') {
|
||||
return;
|
||||
}
|
||||
var b = this.activeThread.nextBlock;
|
||||
|
@ -149,7 +149,7 @@ Interpreter.prototype.stepActiveThread = function() {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Interpreter.prototype.toggleThread = function(b, targetObj) {
|
||||
var newThreads = [], wasRunning = false;
|
||||
|
@ -161,15 +161,15 @@ Interpreter.prototype.toggleThread = function(b, targetObj) {
|
|||
}
|
||||
}
|
||||
this.threads = newThreads;
|
||||
if(!wasRunning) {
|
||||
if (!wasRunning) {
|
||||
this.startThread(b, targetObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Interpreter.prototype.startThread = function(b, targetObj) {
|
||||
this.activeThread = new Thread(b, targetObj);
|
||||
this.threads.push(this.activeThread);
|
||||
}
|
||||
};
|
||||
|
||||
Interpreter.prototype.restartThread = function(b, targetObj) {
|
||||
// used by broadcast; stop any thread running on b, then start a new thread on b
|
||||
|
@ -184,7 +184,7 @@ Interpreter.prototype.restartThread = function(b, targetObj) {
|
|||
if (!wasRunning) {
|
||||
this.threads.push(newThread);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Interpreter.prototype.arg = function(block, index) {
|
||||
var arg = block.args[index];
|
||||
|
@ -193,11 +193,11 @@ Interpreter.prototype.arg = function(block, index) {
|
|||
return arg.primFcn(arg); // expression
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
};
|
||||
|
||||
Interpreter.prototype.targetSprite = function() {
|
||||
return this.activeThread.target;
|
||||
}
|
||||
};
|
||||
|
||||
// Timer
|
||||
Interpreter.prototype.startTimer = function(secs) {
|
||||
|
@ -206,7 +206,7 @@ Interpreter.prototype.startTimer = function(secs) {
|
|||
this.activeThread.tmp = this.currentMSecs + waitMSecs; // end time in milliseconds
|
||||
this.activeThread.firstTime = false;
|
||||
this.yield = true;
|
||||
}
|
||||
};
|
||||
|
||||
Interpreter.prototype.checkTimer = function() {
|
||||
// check for timer expiration and clean up if expired. return true when expired
|
||||
|
@ -219,11 +219,11 @@ Interpreter.prototype.checkTimer = function() {
|
|||
this.yield = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Interpreter.prototype.redraw = function() {
|
||||
this.doRedraw = true;
|
||||
}
|
||||
};
|
||||
|
||||
// Primitive operations
|
||||
Interpreter.prototype.initPrims = function() {
|
||||
|
@ -231,14 +231,14 @@ Interpreter.prototype.initPrims = function() {
|
|||
this.primitiveTable['whenGreenFlag'] = this.primNoop;
|
||||
this.primitiveTable['whenKeyPressed'] = this.primNoop;
|
||||
this.primitiveTable['whenClicked'] = this.primNoop;
|
||||
this.primitiveTable['if'] = function(b) { if (interp.arg(b, 0)) interp.startSubstack(b) };
|
||||
this.primitiveTable['doForever'] = function(b) { interp.startSubstack(b, true) };
|
||||
this.primitiveTable['if'] = function(b) { if (interp.arg(b, 0)) interp.startSubstack(b); };
|
||||
this.primitiveTable['doForever'] = function(b) { interp.startSubstack(b, true); };
|
||||
this.primitiveTable['doForeverIf'] = function(b) { if (interp.arg(b, 0)) interp.startSubstack(b, true); else interp.yield = true; };
|
||||
this.primitiveTable['doIf'] = function(b) { if (interp.arg(b, 0)) interp.startSubstack(b); };
|
||||
this.primitiveTable['doRepeat'] = this.primRepeat;
|
||||
this.primitiveTable['doIfElse'] = function(b) { if (interp.arg(b, 0)) interp.startSubstack(b); else interp.startSubstack(b, false, true); };
|
||||
this.primitiveTable['doWaitUntil'] = function(b) { if (!interp.arg(b, 0)) interp.yield = true };
|
||||
this.primitiveTable['doUntil'] = function(b) { if (!interp.arg(b, 0)) interp.startSubstack(b, true) };
|
||||
this.primitiveTable['doWaitUntil'] = function(b) { if (!interp.arg(b, 0)) interp.yield = true; };
|
||||
this.primitiveTable['doUntil'] = function(b) { if (!interp.arg(b, 0)) interp.startSubstack(b, true); };
|
||||
this.primitiveTable['doReturn'] = function(b) { interp.activeThread = new Thread(null); };
|
||||
this.primitiveTable['stopAll'] = function(b) { interp.activeThread = new Thread(null); interp.threads = []; }
|
||||
this.primitiveTable['whenIReceive'] = this.primNoop;
|
||||
|
@ -247,26 +247,26 @@ Interpreter.prototype.initPrims = function() {
|
|||
this.primitiveTable['wait:elapsed:from:'] = this.primWait;
|
||||
|
||||
// added by John:
|
||||
this.primitiveTable['showBubble'] = function(b) { console.log(interp.arg(b, 1)) }
|
||||
this.primitiveTable['timerReset'] = function(b) {interp.timerBase = (new Date()).getTime() }
|
||||
this.primitiveTable['timer'] = function(b) {return ((new Date()).getTime() - interp.timerBase) / 1000 }
|
||||
this.primitiveTable['showBubble'] = function(b) { console.log(interp.arg(b, 1)); };
|
||||
this.primitiveTable['timerReset'] = function(b) { interp.timerBase = Date.now(); };
|
||||
this.primitiveTable['timer'] = function(b) { return (Date.now() - interp.timerBase) / 1000; };
|
||||
|
||||
new Primitives().addPrimsTo(this.primitiveTable);
|
||||
}
|
||||
};
|
||||
|
||||
Interpreter.prototype.timerBase = (new Date()).getTime();
|
||||
Interpreter.prototype.timerBase = Date.now();
|
||||
Interpreter.prototype.lookupPrim = function(op) {
|
||||
var fcn = interp.primitiveTable[op];
|
||||
if (fcn == null) fcn = function(b) { console.log('not implemented: ' + b.op) }
|
||||
if (fcn == null) fcn = function(b) { console.log('not implemented: ' + b.op); };
|
||||
return fcn;
|
||||
}
|
||||
};
|
||||
|
||||
Interpreter.prototype.primNoop = function(b) { console.log(b.op); }
|
||||
Interpreter.prototype.primNoop = function(b) { console.log(b.op); };
|
||||
|
||||
Interpreter.prototype.primWait = function(b) {
|
||||
if (interp.activeThread.firstTime) interp.startTimer(interp.arg(b, 0));
|
||||
else interp.checkTimer();
|
||||
}
|
||||
};
|
||||
|
||||
Interpreter.prototype.primRepeat = function(b) {
|
||||
if (b.tmp == -1) {
|
||||
|
@ -280,14 +280,14 @@ Interpreter.prototype.primRepeat = function(b) {
|
|||
b.tmp = -1;
|
||||
b = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Interpreter.prototype.broadcast = function(b, waitFlag) {
|
||||
var pair;
|
||||
if (interp.activeThread.firstTime) {
|
||||
var receivers = [];
|
||||
var msg = String(interp.arg(b, 0)).toLowerCase();
|
||||
var findReceivers = function (stack, target) {
|
||||
var findReceivers = function(stack, target) {
|
||||
if ((stack.op == "whenIReceive") && (stack.args[0].toLowerCase() == msg)) {
|
||||
receivers.push([stack, target]);
|
||||
}
|
||||
|
@ -310,7 +310,7 @@ Interpreter.prototype.broadcast = function(b, waitFlag) {
|
|||
} else {
|
||||
interp.yield = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Interpreter.prototype.isRunning = function(b) {
|
||||
for (t in interp.threads) {
|
||||
|
@ -319,7 +319,7 @@ Interpreter.prototype.isRunning = function(b) {
|
|||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Interpreter.prototype.startSubstack = function(b, isLoop, secondSubstack) {
|
||||
// Start the substack of a control structure command such as if or forever.
|
||||
|
@ -327,9 +327,9 @@ Interpreter.prototype.startSubstack = function(b, isLoop, secondSubstack) {
|
|||
b.isLoop = true;
|
||||
this.activeThread.stack.push(b); // remember the block that started the substack
|
||||
}
|
||||
if(!secondSubstack) {
|
||||
if (!secondSubstack) {
|
||||
this.activeThread.nextBlock = b.substack;
|
||||
} else {
|
||||
this.activeThread.nextBlock = b.substack2;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -33,7 +33,7 @@ var Reporter = function(data) {
|
|||
this.el = null; // jQuery Element for the outer box
|
||||
this.valueEl = null; // jQ element containing the reporter value
|
||||
this.slider = null; // slider jQ element
|
||||
}
|
||||
};
|
||||
|
||||
Reporter.prototype.attach = function(scene) {
|
||||
switch (this.mode) {
|
||||
|
@ -68,13 +68,13 @@ Reporter.prototype.attach = function(scene) {
|
|||
this.valueEl.css('background-color', 'rgb(' + cR + ',' + cG + ',' + cB + ')');
|
||||
this.el.css('display', this.visible ? 'inline-block' : 'none');
|
||||
scene.append(this.el);
|
||||
}
|
||||
};
|
||||
|
||||
Reporter.prototype.update = function() {
|
||||
this.el.css('display', this.visible ? 'inline-block' : 'none');
|
||||
if (!this.visible) return;
|
||||
|
||||
var newValue ='';
|
||||
var newValue = '';
|
||||
var target = runtime.spriteNamed(this.target);
|
||||
switch (this.cmd) {
|
||||
case 'getVar:':
|
||||
|
@ -104,17 +104,18 @@ Reporter.prototype.update = function() {
|
|||
break;
|
||||
}
|
||||
this.valueEl.html(newValue);
|
||||
if (this.mode == 3)
|
||||
if (this.mode == 3) {
|
||||
this.slider.val(parseInt(newValue));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reporter.prototype.updateLayer = function() {
|
||||
this.el.css('z-index', this.z);
|
||||
}
|
||||
};
|
||||
|
||||
Reporter.prototype.changeSlider = function() {
|
||||
var newValue = parseInt($(this).val());
|
||||
var target = runtime.spriteNamed($(this).attr('data-target'));
|
||||
var variable = $(this).attr('data-var');
|
||||
target.variables[variable] = newValue;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -35,7 +35,7 @@ var Runtime = function() {
|
|||
this.audioPlaying = [];
|
||||
this.notesPlaying = [];
|
||||
this.projectLoaded = false;
|
||||
}
|
||||
};
|
||||
|
||||
// Initializer for the drawing and audio contexts.
|
||||
Runtime.prototype.init = function() {
|
||||
|
@ -44,7 +44,7 @@ Runtime.prototype.init = function() {
|
|||
this.audioContext = new AudioContext();
|
||||
this.audioGain = this.audioContext.createGainNode();
|
||||
this.audioGain.connect(runtime.audioContext.destination);
|
||||
}
|
||||
};
|
||||
|
||||
// Load start waits for the stage and the sprites to be loaded, without
|
||||
// hanging the browser. When the loading is finished, we begin the step
|
||||
|
@ -69,7 +69,7 @@ Runtime.prototype.loadStart = function() {
|
|||
$('#info').html("Loaded!");
|
||||
setInterval(this.step, 33);
|
||||
this.projectLoaded = true;
|
||||
}
|
||||
};
|
||||
|
||||
Runtime.prototype.greenFlag = function() {
|
||||
if (this.projectLoaded) {
|
||||
|
@ -78,7 +78,7 @@ Runtime.prototype.greenFlag = function() {
|
|||
interp.primitiveTable.timerReset();
|
||||
this.startGreenFlags();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Runtime.prototype.stopAll = function() {
|
||||
interp.activeThread = new Thread(null);
|
||||
|
@ -86,10 +86,11 @@ Runtime.prototype.stopAll = function() {
|
|||
stopAllSounds();
|
||||
// Hide reporters
|
||||
for (var s = 0; s < runtime.sprites.length; s++) {
|
||||
if (typeof runtime.sprites[s].hideBubble == 'function')
|
||||
if (typeof runtime.sprites[s].hideBubble == 'function') {
|
||||
runtime.sprites[s].hideBubble();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Step method for execution - called every 33 milliseconds
|
||||
Runtime.prototype.step = function() {
|
||||
|
@ -97,7 +98,7 @@ Runtime.prototype.step = function() {
|
|||
for (var r = 0; r < runtime.reporters.length; r++) {
|
||||
runtime.reporters[r].update();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Stack functions -- push and remove stacks
|
||||
// to be run by the interpreter as threads.
|
||||
|
@ -106,7 +107,7 @@ Runtime.prototype.allStacksDo = function(f) {
|
|||
var stack;
|
||||
for (var i = runtime.sprites.length-1; i >= 0; i--) {
|
||||
var o = runtime.sprites[i];
|
||||
if(typeof(o) == 'object' && o.constructor == Sprite) {
|
||||
if (typeof(o) == 'object' && o.constructor == Sprite) {
|
||||
$.each(o.stacks, function(index, stack) {
|
||||
f(stack, o);
|
||||
});
|
||||
|
@ -115,7 +116,7 @@ Runtime.prototype.allStacksDo = function(f) {
|
|||
$.each(stage.stacks, function(index, stack) {
|
||||
f(stack, stage);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Hat triggers
|
||||
Runtime.prototype.startGreenFlags = function() {
|
||||
|
@ -123,7 +124,7 @@ Runtime.prototype.startGreenFlags = function() {
|
|||
if (stack.op == 'whenGreenFlag') interp.toggleThread(stack, target);
|
||||
}
|
||||
this.allStacksDo(startIfGreenFlag);
|
||||
}
|
||||
};
|
||||
|
||||
Runtime.prototype.startKeyHats = function(ch) {
|
||||
var keyName = null;
|
||||
|
@ -140,30 +141,30 @@ Runtime.prototype.startKeyHats = function(ch) {
|
|||
if (ch == 32) keyName = "space";
|
||||
|
||||
if (keyName == null) return;
|
||||
var startMatchingKeyHats = function (stack, target) {
|
||||
var startMatchingKeyHats = function(stack, target) {
|
||||
if ((stack.op == "whenKeyPressed") && (stack.args[0] == keyName)) {
|
||||
// Only start the stack if it is not already running
|
||||
if (!interp.isRunning(stack))
|
||||
if (!interp.isRunning(stack)) {
|
||||
interp.toggleThread(stack, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
runtime.allStacksDo(startMatchingKeyHats);
|
||||
}
|
||||
};
|
||||
|
||||
Runtime.prototype.startClickedHats = function(sprite) {
|
||||
function startIfClicked(stack, target) {
|
||||
if(target == sprite && stack.op == "whenClicked") {
|
||||
if(!interp.isRunning(stack))
|
||||
if (target == sprite && stack.op == "whenClicked" && !interp.isRunning(stack)) {
|
||||
interp.toggleThread(stack, target);
|
||||
}
|
||||
}
|
||||
runtime.allStacksDo(startIfClicked);
|
||||
}
|
||||
};
|
||||
|
||||
// Returns true if a key is pressed.
|
||||
Runtime.prototype.keyIsDown = function(ch) {
|
||||
return this.keysDown[ch] || false;
|
||||
}
|
||||
};
|
||||
|
||||
// Sprite named -- returns one of the sprites on the stage.
|
||||
Runtime.prototype.spriteNamed = function(n) {
|
||||
|
@ -176,7 +177,7 @@ Runtime.prototype.spriteNamed = function(n) {
|
|||
}
|
||||
});
|
||||
return selected_sprite;
|
||||
}
|
||||
};
|
||||
|
||||
Runtime.prototype.getTimeString = function(which) {
|
||||
// Return local time properties.
|
||||
|
@ -191,8 +192,7 @@ Runtime.prototype.getTimeString = function(which) {
|
|||
case 'day of week': return now.getDay() + 1; // 1-7, where 1 is Sunday
|
||||
}
|
||||
return ''; // shouldn't happen
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Reassigns z-indices for layer functions
|
||||
Runtime.prototype.reassignZ = function(target, move) {
|
||||
|
@ -209,7 +209,7 @@ Runtime.prototype.reassignZ = function(target, move) {
|
|||
if (move == null) {
|
||||
// Move to the front
|
||||
this.sprites.splice(this.sprites.length, 0, target);
|
||||
} else if (oldIndex - move >= 0 && oldIndex - move < this.sprites.length+1) {
|
||||
} else if (oldIndex - move >= 0 && oldIndex - move < this.sprites.length + 1) {
|
||||
// Move to the new position
|
||||
this.sprites.splice(oldIndex - move, 0, target);
|
||||
} else {
|
||||
|
@ -224,4 +224,4 @@ Runtime.prototype.reassignZ = function(target, move) {
|
|||
sprite.updateLayer();
|
||||
newZ++;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
'use strict';
|
||||
|
||||
var runtime, interp, io, iosAudioActive = false;
|
||||
$(function () {
|
||||
$(function() {
|
||||
runtime = new Runtime();
|
||||
runtime.init();
|
||||
|
||||
|
|
106
js/Sprite.js
106
js/Sprite.js
|
@ -22,12 +22,12 @@
|
|||
'use strict';
|
||||
|
||||
var Sprite = function(data) {
|
||||
if(!this.data) {
|
||||
if (!this.data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
// Public variables used for Scratch-accessible data.
|
||||
this.visible = (typeof(this.data.visible) == "undefined") ? true : data.visible;
|
||||
this.visible = typeof(this.data.visible) == "undefined" ? true : data.visible;
|
||||
|
||||
this.scratchX = data.scratchX || 0;
|
||||
this.scratchY = data.scratchY || 0;
|
||||
|
@ -94,7 +94,7 @@ var Sprite = function(data) {
|
|||
|
||||
// Stacks to be pushed to the interpreter and run
|
||||
this.stacks = [];
|
||||
}
|
||||
};
|
||||
|
||||
// Attaches a Sprite (<img>) to a Scratch scene
|
||||
Sprite.prototype.attach = function(scene) {
|
||||
|
@ -109,7 +109,7 @@ Sprite.prototype.attach = function(scene) {
|
|||
sprite.costumesLoaded += 1;
|
||||
sprite.updateCostume();
|
||||
|
||||
$(sprite.textures[c]).css('display', (sprite.currentCostumeIndex == c) ? 'inline' : 'none');
|
||||
$(sprite.textures[c]).css('display', sprite.currentCostumeIndex == c ? 'inline' : 'none');
|
||||
$(sprite.textures[c]).css('position', 'absolute').css('left', '0px').css('top', '0px');
|
||||
$(sprite.textures[c]).bind('dragstart', function(evt) { evt.preventDefault(); })
|
||||
.bind('selectstart', function(evt) { evt.preventDefault(); })
|
||||
|
@ -139,21 +139,20 @@ Sprite.prototype.attach = function(scene) {
|
|||
this.talkBubble.append(this.talkBubbleStyler);
|
||||
|
||||
runtime.scene.append(this.talkBubble);
|
||||
}
|
||||
};
|
||||
|
||||
// Load sounds from the server and buffer them
|
||||
Sprite.prototype.loadSounds = function() {
|
||||
var spr = this;
|
||||
$.each(this.sounds, function (index, sound) {
|
||||
$.each(this.sounds, function(index, sound) {
|
||||
io.soundRequest(sound, spr);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// True when all the costumes have been loaded
|
||||
Sprite.prototype.isLoaded = function() {
|
||||
return (this.costumesLoaded == this.costumes.length
|
||||
&& this.soundsLoaded == Object.keys(this.sounds).length);
|
||||
}
|
||||
return this.costumesLoaded == this.costumes.length && this.soundsLoaded == Object.keys(this.sounds).length;
|
||||
};
|
||||
|
||||
// Step methods
|
||||
Sprite.prototype.showCostume = function(costume) {
|
||||
|
@ -167,33 +166,33 @@ Sprite.prototype.showCostume = function(costume) {
|
|||
this.currentCostumeIndex = costume;
|
||||
}
|
||||
this.updateCostume();
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.indexOfCostumeNamed = function(name) {
|
||||
for(var i in this.costumes) {
|
||||
for (var i in this.costumes) {
|
||||
var c = this.costumes[i];
|
||||
if(c['costumeName'] == name) {
|
||||
if (c['costumeName'] == name) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.showCostumeNamed = function(name) {
|
||||
var index = this.indexOfCostumeNamed(name);
|
||||
if(!index) return;
|
||||
if (!index) return;
|
||||
this.showCostume(index);
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.updateCostume = function() {
|
||||
if(!this.textures[this.currentCostumeIndex]) {
|
||||
if (!this.textures[this.currentCostumeIndex]) {
|
||||
this.currentCostumeIndex = 0;
|
||||
}
|
||||
$(this.mesh).css('display', 'none');
|
||||
this.mesh = this.textures[this.currentCostumeIndex];
|
||||
this.updateVisible();
|
||||
this.updateTransform();
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.onClick = function(evt) {
|
||||
// TODO - needs work!!
|
||||
|
@ -238,23 +237,24 @@ Sprite.prototype.onClick = function(evt) {
|
|||
$(underElement).click();
|
||||
$(this.mesh).show();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.setVisible = function(v) {
|
||||
this.visible = v;
|
||||
this.updateVisible();
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.updateLayer = function() {
|
||||
$(this.mesh).css('z-index', this.z);
|
||||
if (this.talkBubble) this.talkBubble.css('z-index', this.z);
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.updateVisible = function() {
|
||||
$(this.mesh).css('display', (this.visible) ? 'inline' : 'none');
|
||||
if (this.talkBubbleOn)
|
||||
this.talkBubble.css('display', (this.visible) ? 'inline-block' : 'none');
|
||||
}
|
||||
$(this.mesh).css('display', this.visible ? 'inline' : 'none');
|
||||
if (this.talkBubbleOn) {
|
||||
this.talkBubble.css('display', this.visible ? 'inline-block' : 'none');
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.updateTransform = function() {
|
||||
var texture = this.textures[this.currentCostumeIndex];
|
||||
|
@ -305,7 +305,7 @@ Sprite.prototype.updateTransform = function() {
|
|||
}
|
||||
|
||||
this.updateLayer();
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.getTalkBubbleXY = function() {
|
||||
var texture = this.textures[this.currentCostumeIndex];
|
||||
|
@ -316,7 +316,7 @@ Sprite.prototype.getTalkBubbleXY = function() {
|
|||
var drawX = this.scratchX + (480 / 2) - rotationCenterX;
|
||||
var drawY = -this.scratchY + (360 / 2) - rotationCenterY;
|
||||
return [drawX + drawWidth, drawY - drawHeight / 2];
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.showBubble = function(text, type) {
|
||||
var xy = this.getTalkBubbleXY();
|
||||
|
@ -329,30 +329,34 @@ Sprite.prototype.showBubble = function(text, type) {
|
|||
|
||||
this.talkBubbleStyler.removeClass('bubble-say');
|
||||
this.talkBubbleStyler.removeClass('bubble-think');
|
||||
if (type == 'say') this.talkBubbleStyler.addClass('bubble-say');
|
||||
else if (type == 'think') this.talkBubbleStyler.addClass('bubble-think');
|
||||
if (type == 'say') {
|
||||
this.talkBubbleStyler.addClass('bubble-say');
|
||||
} else if (type == 'think') {
|
||||
this.talkBubbleStyler.addClass('bubble-think');
|
||||
}
|
||||
|
||||
if (this.visible)
|
||||
if (this.visible) {
|
||||
this.talkBubble.css('display', 'inline-block');
|
||||
}
|
||||
this.talkBubbleBox.html(text);
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.hideBubble = function() {
|
||||
this.talkBubbleOn = false;
|
||||
this.talkBubble.css('display', 'none');
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.setXY = function(x, y) {
|
||||
this.scratchX = x;
|
||||
this.scratchY = y;
|
||||
this.updateTransform();
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.setDirection = function(d) {
|
||||
var rotation;
|
||||
d = d % 360
|
||||
if (d < 0) d += 360;
|
||||
this.direction = (d > 180) ? d - 360 : d;
|
||||
this.direction = d > 180 ? d - 360 : d;
|
||||
if (this.rotationStyle == 'normal') {
|
||||
rotation = (this.direction - 90) % 360;
|
||||
} else if (this.rotationStyle == 'leftRight') {
|
||||
|
@ -367,22 +371,22 @@ Sprite.prototype.setDirection = function(d) {
|
|||
}
|
||||
this.rotation = rotation;
|
||||
this.updateTransform();
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.setRotationStyle = function(r) {
|
||||
this.rotationStyle = r;
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.getSize = function() {
|
||||
return this.scale * 100;
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.setSize = function(percent) {
|
||||
var newScale = percent / 100.0;
|
||||
newScale = Math.max(0.05, Math.min(newScale, 100));
|
||||
this.scale = newScale;
|
||||
this.updateTransform();
|
||||
}
|
||||
};
|
||||
|
||||
// Move functions
|
||||
Sprite.prototype.keepOnStage = function() {
|
||||
|
@ -398,7 +402,7 @@ Sprite.prototype.keepOnStage = function() {
|
|||
if (myBox.top > edgeBox.bottom) y -= myBox.top - edgeBox.bottom;
|
||||
this.scratchX = x - 240;
|
||||
this.scratchY = 180 - y;
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.getRect = function() {
|
||||
var cImg = this.textures[this.currentCostumeIndex];
|
||||
|
@ -406,7 +410,7 @@ Sprite.prototype.getRect = function() {
|
|||
var y = 180 - this.scratchY - (cImg.height/2.0);
|
||||
var myBox = new Rectangle(x, y, cImg.width, cImg.height);
|
||||
return myBox;
|
||||
}
|
||||
};
|
||||
|
||||
// Pen functions
|
||||
Sprite.prototype.setPenColor = function(c) {
|
||||
|
@ -414,26 +418,29 @@ Sprite.prototype.setPenColor = function(c) {
|
|||
this.penHue = (200 * hsv[0]) / 360 ;
|
||||
this.penShade = 50 * hsv[2]; // not quite right; doesn't account for saturation
|
||||
this.penColorCache = c;
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.setPenHue = function(n) {
|
||||
this.penHue = n % 200;
|
||||
if (this.penHue < 0) this.penHue += 200;
|
||||
this.updateCachedPenColor();
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.setPenShade = function(n) {
|
||||
this.penShade = n % 200;
|
||||
if (this.penShade < 0) this.penShade += 200;
|
||||
this.updateCachedPenColor();
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.updateCachedPenColor = function() {
|
||||
var c = Color.fromHSV((this.penHue * 180.0) / 100.0, 1, 1);
|
||||
var shade = (this.penShade > 100) ? 200 - this.penShade : this.penShade; // range 0..100
|
||||
var shade = this.penShade > 100 ? 200 - this.penShade : this.penShade; // range 0..100
|
||||
if (shade < 50) {
|
||||
this.penColorCache = Color.mixRGB(0, c, (10 + shade) / 60.0);
|
||||
} else {
|
||||
this.penColorCache = Color.mixRGB(c, 0xFFFFFF, (shade - 50) / 60);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.stamp = function(canvas, opacity) {
|
||||
var drawWidth = this.textures[this.currentCostumeIndex].width * this.scale;
|
||||
|
@ -447,12 +454,13 @@ Sprite.prototype.stamp = function(canvas, opacity) {
|
|||
canvas.drawImage(this.mesh, -drawWidth/2, -drawHeight/2, drawWidth, drawHeight);
|
||||
canvas.restore();
|
||||
canvas.globalAlpha = 1;
|
||||
}
|
||||
};
|
||||
|
||||
Sprite.prototype.soundNamed = function(name) {
|
||||
if (name in this.sounds && this.sounds[name].buffer)
|
||||
if (name in this.sounds && this.sounds[name].buffer) {
|
||||
return this.sounds[name];
|
||||
else if (name in runtime.stage.sounds && runtime.stage.sounds[name].buffer)
|
||||
} else if (name in runtime.stage.sounds && runtime.stage.sounds[name].buffer) {
|
||||
return runtime.stage.sounds[name];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
|
17
js/Stage.js
17
js/Stage.js
|
@ -35,30 +35,27 @@ var Stage = function(data) {
|
|||
this.lineCache = this.lineCanvas.getContext('2d');
|
||||
|
||||
Sprite.call(this, data);
|
||||
}
|
||||
};
|
||||
|
||||
Stage.prototype = Object.create(Sprite.prototype);
|
||||
Stage.prototype.constructor = Stage;
|
||||
|
||||
Stage.prototype.attachPenLayer = function(scene) {
|
||||
if (this.penLayerLoaded)
|
||||
return;
|
||||
if (this.penLayerLoaded) return;
|
||||
this.penLayerLoaded = true;
|
||||
$(this.lineCanvas).css('position', 'absolute');
|
||||
$(this.lineCanvas).css('z-index', '-1');
|
||||
scene.append(this.lineCanvas);
|
||||
}
|
||||
};
|
||||
|
||||
Stage.prototype.isLoaded = function() {
|
||||
return (this.penLayerLoaded
|
||||
&& this.costumesLoaded == this.costumes.length
|
||||
&& this.soundsLoaded == Object.keys(this.sounds).length);
|
||||
}
|
||||
return this.penLayerLoaded && this.costumesLoaded == this.costumes.length && this.soundsLoaded == Object.keys(this.sounds).length;
|
||||
};
|
||||
|
||||
// Pen functions
|
||||
Stage.prototype.clearPenStrokes = function() {
|
||||
this.lineCache.clearRect(0, 0, 480, 360);
|
||||
}
|
||||
};
|
||||
|
||||
Stage.prototype.stroke = function(from, to, width, color) {
|
||||
this.lineCache.lineWidth = width;
|
||||
|
@ -69,4 +66,4 @@ Stage.prototype.stroke = function(from, to, width, color) {
|
|||
this.lineCache.lineTo(to[0] + 240.5, 180.5 - to[1]);
|
||||
this.lineCache.strokeStyle = 'rgb(' + (color >> 16) + ',' + (color >> 8 & 255) + ',' + (color & 255) + ')';
|
||||
this.lineCache.stroke();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var LooksPrims = function() {}
|
||||
var LooksPrims = function() {};
|
||||
|
||||
LooksPrims.prototype.addPrimsTo = function(primTable) {
|
||||
primTable["show"] = this.primShow;
|
||||
|
@ -47,22 +47,22 @@ LooksPrims.prototype.addPrimsTo = function(primTable) {
|
|||
primTable["say:duration:elapsed:from:"] = function(b) { showBubbleAndWait(b, 'say'); };
|
||||
primTable["think:"] = function(b) { showBubble(b, 'think'); };
|
||||
primTable["think:duration:elapsed:from:"] = function(b) { showBubbleAndWait(b, 'think'); };
|
||||
}
|
||||
};
|
||||
|
||||
LooksPrims.prototype.primShow = function(b) {
|
||||
interp.targetSprite().setVisible(true);
|
||||
interp.redraw();
|
||||
}
|
||||
};
|
||||
|
||||
LooksPrims.prototype.primHide = function(b) {
|
||||
interp.targetSprite().setVisible(false);
|
||||
interp.redraw();
|
||||
}
|
||||
};
|
||||
|
||||
LooksPrims.prototype.primNextCostume = function(b) {
|
||||
interp.targetSprite().showCostume(interp.targetSprite().currentCostumeIndex + 1);
|
||||
interp.redraw();
|
||||
}
|
||||
};
|
||||
|
||||
LooksPrims.prototype.primShowCostume = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
|
@ -88,7 +88,7 @@ LooksPrims.prototype.primShowCostume = function(b) {
|
|||
}
|
||||
}
|
||||
if (s.visible) interp.redraw();
|
||||
}
|
||||
};
|
||||
|
||||
LooksPrims.prototype.primStartScene = function(b) {
|
||||
var s = runtime.stage;
|
||||
|
@ -113,55 +113,55 @@ LooksPrims.prototype.primStartScene = function(b) {
|
|||
}
|
||||
}
|
||||
if (s.visible) interp.redraw();
|
||||
}
|
||||
};
|
||||
|
||||
LooksPrims.prototype.primCostumeNum = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
return (s == null) ? 1 : s.currentCostumeIndex + 1;
|
||||
}
|
||||
return s == null ? 1 : s.currentCostumeIndex + 1;
|
||||
};
|
||||
|
||||
LooksPrims.prototype.primChangeSize = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s == null) return;
|
||||
s.setSize(s.getSize() + interp.arg(b, 0));
|
||||
if (s.visible) interp.redraw();
|
||||
}
|
||||
};
|
||||
|
||||
LooksPrims.prototype.primSetSize = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s == null) return;
|
||||
s.setSize(interp.arg(b, 0));
|
||||
if (s.visible) interp.redraw();
|
||||
}
|
||||
};
|
||||
|
||||
LooksPrims.prototype.primSize = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s == null) return 100;
|
||||
return s.getSize();
|
||||
}
|
||||
};
|
||||
|
||||
LooksPrims.prototype.primGoFront = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
runtime.reassignZ(s, null);
|
||||
if(s.visible) interp.redraw();
|
||||
}
|
||||
if (s.visible) interp.redraw();
|
||||
};
|
||||
|
||||
LooksPrims.prototype.primGoBack = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
runtime.reassignZ(s, interp.arg(b, 0));
|
||||
if(s.visible) interp.redraw();
|
||||
}
|
||||
if (s.visible) interp.redraw();
|
||||
};
|
||||
|
||||
LooksPrims.prototype.primChangeEffect = function(b) {}
|
||||
LooksPrims.prototype.primChangeEffect = function(b) {};
|
||||
|
||||
LooksPrims.prototype.primSetEffect = function(b) {}
|
||||
LooksPrims.prototype.primSetEffect = function(b) {};
|
||||
|
||||
LooksPrims.prototype.primClearEffects = function(b) {}
|
||||
LooksPrims.prototype.primClearEffects = function(b) {};
|
||||
|
||||
var showBubble = function(b, type) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) s.showBubble(interp.arg(b, 0), type);
|
||||
}
|
||||
};
|
||||
|
||||
var showBubbleAndWait = function(b, type) {
|
||||
var s = interp.targetSprite();
|
||||
|
@ -175,4 +175,4 @@ var showBubbleAndWait = function(b, type) {
|
|||
} else {
|
||||
if (interp.checkTimer()) s.hideBubble();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var MotionAndPenPrims = function() {}
|
||||
var MotionAndPenPrims = function() {};
|
||||
|
||||
MotionAndPenPrims.prototype.addPrimsTo = function(primTable) {
|
||||
primTable['forward:'] = this.primMove;
|
||||
|
@ -52,60 +52,59 @@ MotionAndPenPrims.prototype.addPrimsTo = function(primTable) {
|
|||
|
||||
primTable["stampCostume"] = this.primStamp;
|
||||
primTable["stampTransparent"] = this.primStampTransparent;
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primMove = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
var radians = ((Math.PI * (90 - s.direction)) / 180);
|
||||
var radians = (90 - s.direction) * Math.PI / 180;
|
||||
var d = interp.arg(b, 0);
|
||||
|
||||
moveSpriteTo(s, s.scratchX + (d * Math.cos(radians)),
|
||||
s.scratchY + (d * Math.sin(radians)));
|
||||
if(s.visible) interp.redraw();
|
||||
}
|
||||
moveSpriteTo(s, s.scratchX + d * Math.cos(radians), s.scratchY + d * Math.sin(radians));
|
||||
if (s.visible) interp.redraw();
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primTurnLeft = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
var d = s.direction - interp.arg(b, 0);
|
||||
s.setDirection(d);
|
||||
if(s.visible) interp.redraw();
|
||||
}
|
||||
if (s.visible) interp.redraw();
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primTurnRight = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
var d = s.direction + interp.arg(b, 0);
|
||||
s.setDirection(d);
|
||||
if(s.visible) interp.redraw();
|
||||
}
|
||||
if (s.visible) interp.redraw();
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primSetDirection = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
s.setDirection(interp.arg(b, 0));
|
||||
if(s.visible) interp.redraw();
|
||||
}
|
||||
if (s.visible) interp.redraw();
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primPointTowards = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
var p = mouseOrSpritePosition(interp.arg(b, 0));
|
||||
if ((s == null) || (p == null)) return;
|
||||
if (s == null || p == null) return;
|
||||
var dx = p.x - s.scratchX;
|
||||
var dy = p.y - s.scratchY;
|
||||
var angle = 90 - ((Math.atan2(dy, dx) * 180) / Math.PI);
|
||||
var angle = 90 - Math.atan2(dy, dx) * 180 / Math.PI;
|
||||
s.setDirection(angle);
|
||||
if (s.visible) interp.redraw();
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primGoTo = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) moveSpriteTo(s, interp.arg(b, 0), interp.arg(b, 1));
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primGoToSpriteOrMouse = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
var p = mouseOrSpritePosition(interp.arg(b, 0));
|
||||
if ((s == null) || (p == null)) return;
|
||||
if (s == null || p == null) return;
|
||||
moveSpriteTo(s, p.x, p.y);
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primGlide = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
|
@ -119,16 +118,15 @@ MotionAndPenPrims.prototype.primGlide = function(b) {
|
|||
return;
|
||||
}
|
||||
// record state: [0]start msecs, [1]duration, [2]startX, [3]startY, [4]endX, [5]endY
|
||||
interp.activeThread.tmpObj =
|
||||
[interp.currentMSecs, 1000 * secs, s.scratchX, s.scratchY, destX, destY];
|
||||
interp.activeThread.tmpObj = [interp.currentMSecs, 1000 * secs, s.scratchX, s.scratchY, destX, destY];
|
||||
interp.startTimer(secs);
|
||||
} else {
|
||||
var state = interp.activeThread.tmpObj;
|
||||
if (!interp.checkTimer()) {
|
||||
// in progress: move to intermediate position along path
|
||||
var frac = (interp.currentMSecs - state[0]) / state[1];
|
||||
var newX = state[2] + (frac * (state[4] - state[2]));
|
||||
var newY = state[3] + (frac * (state[5] - state[3]));
|
||||
var newX = state[2] + frac * (state[4] - state[2]);
|
||||
var newY = state[3] + frac * (state[5] - state[3]);
|
||||
moveSpriteTo(s, newX, newY);
|
||||
} else {
|
||||
// finished: move to final position and clear state
|
||||
|
@ -136,27 +134,27 @@ MotionAndPenPrims.prototype.primGlide = function(b) {
|
|||
interp.activeThread.tmpObj = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primChangeX = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) moveSpriteTo(s, s.scratchX + interp.arg(b, 0), s.scratchY);
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primSetX = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) moveSpriteTo(s, interp.arg(b, 0), s.scratchY);
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primChangeY = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) moveSpriteTo(s, s.scratchX, s.scratchY + interp.arg(b, 0));
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primSetY = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) moveSpriteTo(s, s.scratchX, interp.arg(b, 0));
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primBounceOffEdge = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
|
@ -164,7 +162,7 @@ MotionAndPenPrims.prototype.primBounceOffEdge = function(b) {
|
|||
if (!turnAwayFromEdge(s)) return;
|
||||
ensureOnStageOnBounce(s);
|
||||
if (s.visible) interp.redraw();
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primSetRotationStyle = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
|
@ -175,95 +173,94 @@ MotionAndPenPrims.prototype.primSetRotationStyle = function(b) {
|
|||
else if (request == 'left-right') rotationStyle = 'leftRight';
|
||||
else if (request == 'none') rotationStyle = 'none';
|
||||
s.setRotationStyle(rotationStyle);
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primXPosition = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
return (s != null) ? s.scratchX : 0;
|
||||
}
|
||||
return s != null ? s.scratchX : 0;
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primYPosition = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
return (s != null) ? s.scratchY : 0;
|
||||
}
|
||||
return s != null ? s.scratchY : 0;
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primDirection = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
return (s != null) ? s.direction : 0;
|
||||
}
|
||||
return s != null ? s.direction : 0;
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primClear = function(b) {
|
||||
runtime.stage.clearPenStrokes();
|
||||
interp.redraw();
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primPenDown = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) s.penIsDown = true;
|
||||
stroke(s, s.scratchX, s.scratchY, s.scratchX + 0.2, s.scratchY + 0.2);
|
||||
interp.redraw();
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primPenUp = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) s.penIsDown = false;
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primSetPenColor = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) s.setPenColor(interp.arg(b, 0));
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primSetPenHue = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) s.setPenHue(interp.arg(b, 0));
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primChangePenHue = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) s.setPenHue(s.penHue + interp.arg(b, 0));
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primSetPenShade = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) s.setPenShade(interp.arg(b, 0));
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primChangePenShade = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) s.setPenShade(s.penShade + interp.arg(b, 0));
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primSetPenSize = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
var w = Math.max(0, Math.min(interp.arg(b, 0), 100));
|
||||
if (s != null) s.penWidth = w;
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primChangePenSize = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
var w = Math.max(0, Math.min(s.penWidth + interp.arg(b, 0), 100));
|
||||
if (s != null) s.penWidth = w;
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primStamp = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
s.stamp(runtime.stage.lineCache, 100);
|
||||
}
|
||||
};
|
||||
|
||||
MotionAndPenPrims.prototype.primStampTransparent = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
var transparency = Math.max(0, Math.min(interp.arg(b, 0), 100));
|
||||
var alpha = 100 - transparency;
|
||||
s.stamp(runtime.stage.lineCache, alpha);
|
||||
}
|
||||
};
|
||||
|
||||
// Helpers
|
||||
var stroke = function(s, oldX, oldY, newX, newY) {
|
||||
runtime.stage.stroke([oldX, oldY],
|
||||
[newX, newY], s.penWidth, s.penColorCache);
|
||||
runtime.stage.stroke([oldX, oldY], [newX, newY], s.penWidth, s.penColorCache);
|
||||
interp.redraw();
|
||||
}
|
||||
};
|
||||
|
||||
var mouseOrSpritePosition = function(arg) {
|
||||
if (arg == "_mouse_") {
|
||||
|
@ -275,7 +272,7 @@ var mouseOrSpritePosition = function(arg) {
|
|||
return new Point(s.scratchX, s.scratchY);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
var moveSpriteTo = function(s, newX, newY) {
|
||||
var oldX = s.scratchX;
|
||||
|
@ -283,8 +280,8 @@ var moveSpriteTo = function(s, newX, newY) {
|
|||
s.setXY(newX, newY);
|
||||
s.keepOnStage();
|
||||
if (s.penIsDown) stroke(s, oldX, oldY, s.scratchX, s.scratchY);
|
||||
if ((s.penIsDown) || (s.visible)) interp.redraw();
|
||||
}
|
||||
if (s.penIsDown || s.visible) interp.redraw();
|
||||
};
|
||||
|
||||
var turnAwayFromEdge = function(s) {
|
||||
// turn away from the nearest edge if it's close enough; otherwise do nothing
|
||||
|
@ -298,23 +295,23 @@ var turnAwayFromEdge = function(s) {
|
|||
var d4 = Math.max(0, 360 - r.bottom);
|
||||
// find the nearest edge
|
||||
var e = 0, minDist = 100000;
|
||||
if (d1 < minDist) { minDist = d1; e = 1 }
|
||||
if (d2 < minDist) { minDist = d2; e = 2 }
|
||||
if (d3 < minDist) { minDist = d3; e = 3 }
|
||||
if (d4 < minDist) { minDist = d4; e = 4 }
|
||||
if (d1 < minDist) { minDist = d1; e = 1; }
|
||||
if (d2 < minDist) { minDist = d2; e = 2; }
|
||||
if (d3 < minDist) { minDist = d3; e = 3; }
|
||||
if (d4 < minDist) { minDist = d4; e = 4; }
|
||||
if (minDist > 0) return false; // not touching to any edge
|
||||
// point away from nearest edge
|
||||
var radians = ((90 - s.direction) * Math.PI) / 180;
|
||||
var radians = (90 - s.direction) * Math.PI / 180;
|
||||
var dx = Math.cos(radians);
|
||||
var dy = -Math.sin(radians);
|
||||
if (e == 1) { dx = Math.max(0.2, Math.abs(dx)) }
|
||||
if (e == 2) { dy = Math.max(0.2, Math.abs(dy)) }
|
||||
if (e == 3) { dx = 0 - Math.max(0.2, Math.abs(dx)) }
|
||||
if (e == 4) { dy = 0 - Math.max(0.2, Math.abs(dy)) }
|
||||
var newDir = ((180 * Math.atan2(dy, dx)) / Math.PI) + 90;
|
||||
if (e == 1) { dx = Math.max(0.2, Math.abs(dx)); }
|
||||
if (e == 2) { dy = Math.max(0.2, Math.abs(dy)); }
|
||||
if (e == 3) { dx = 0 - Math.max(0.2, Math.abs(dx)); }
|
||||
if (e == 4) { dy = 0 - Math.max(0.2, Math.abs(dy)); }
|
||||
var newDir = Math.atan2(dy, dx) * 180 / Math.PI + 90;
|
||||
s.direction = newDir;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
var ensureOnStageOnBounce = function(s) {
|
||||
var r = s.getRect();
|
||||
|
@ -326,4 +323,4 @@ var ensureOnStageOnBounce = function(s) {
|
|||
if (r.bottom > 360) {
|
||||
moveSpriteTo(s, s.scratchX, s.scratchY + (r.bottom - 360));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -26,29 +26,29 @@ var Primitives = function() {}
|
|||
|
||||
Primitives.prototype.addPrimsTo = function(primTable) {
|
||||
// Math primitives
|
||||
primTable["+"] = function(b) { return interp.arg(b, 0) + interp.arg(b, 1) };
|
||||
primTable["-"] = function(b) { return interp.arg(b, 0) - interp.arg(b, 1) };
|
||||
primTable["*"] = function(b) { return interp.arg(b, 0) * interp.arg(b, 1) };
|
||||
primTable["/"] = function(b) { return interp.arg(b, 0) / interp.arg(b, 1) };
|
||||
primTable["%"] = function(b) { return interp.arg(b, 0) % interp.arg(b, 1) };
|
||||
primTable["+"] = function(b) { return interp.arg(b, 0) + interp.arg(b, 1); };
|
||||
primTable["-"] = function(b) { return interp.arg(b, 0) - interp.arg(b, 1); };
|
||||
primTable["*"] = function(b) { return interp.arg(b, 0) * interp.arg(b, 1); };
|
||||
primTable["/"] = function(b) { return interp.arg(b, 0) / interp.arg(b, 1); };
|
||||
primTable["%"] = function(b) { return interp.arg(b, 0) % interp.arg(b, 1); };
|
||||
primTable["randomFrom:to:"] = this.primRandom;
|
||||
primTable["<"] = function(b) { return (interp.arg(b, 0) < interp.arg(b, 1)) };
|
||||
primTable["="] = function(b) { return (interp.arg(b, 0) == interp.arg(b, 1)) };
|
||||
primTable[">"] = function(b) { return (interp.arg(b, 0) > interp.arg(b, 1)) };
|
||||
primTable["&"] = function(b) { return interp.arg(b, 0) && interp.arg(b, 1) };
|
||||
primTable["|"] = function(b) { return interp.arg(b, 0) || interp.arg(b, 1) };
|
||||
primTable["<"] = function(b) { return (interp.arg(b, 0) < interp.arg(b, 1)); };
|
||||
primTable["="] = function(b) { return (interp.arg(b, 0) == interp.arg(b, 1)); };
|
||||
primTable[">"] = function(b) { return (interp.arg(b, 0) > interp.arg(b, 1)); };
|
||||
primTable["&"] = function(b) { return interp.arg(b, 0) && interp.arg(b, 1); };
|
||||
primTable["|"] = function(b) { return interp.arg(b, 0) || interp.arg(b, 1); };
|
||||
primTable["not"] = function(b) { return !interp.arg(b, 0) };
|
||||
primTable["abs"] = function(b) { return Math.abs(interp.arg(b, 0)) };
|
||||
primTable["sqrt"] = function(b) { return Math.sqrt(interp.arg(b, 0)) };
|
||||
|
||||
primTable["\\\\"] = this.primModulo;
|
||||
primTable["rounded"] = function(b) { return Math.round(interp.arg(b, 0)) };
|
||||
primTable["rounded"] = function(b) { return Math.round(interp.arg(b, 0)); };
|
||||
primTable["computeFunction:of:"] = this.primMathFunction;
|
||||
|
||||
// String primitives
|
||||
primTable["concatenate:with:"] = function(b) { return "" + interp.arg(b, 0) + interp.arg(b, 1) };
|
||||
primTable["concatenate:with:"] = function(b) { return "" + interp.arg(b, 0) + interp.arg(b, 1); };
|
||||
primTable["letter:of:"] = this.primLetterOf;
|
||||
primTable["stringLength:"] = function(b) { return interp.arg(b, 0).length };
|
||||
primTable["stringLength:"] = function(b) { return interp.arg(b, 0).length; };
|
||||
|
||||
new VarListPrims().addPrimsTo(primTable);
|
||||
new MotionAndPenPrims().addPrimsTo(primTable);
|
||||
|
@ -60,20 +60,20 @@ Primitives.prototype.addPrimsTo = function(primTable) {
|
|||
Primitives.prototype.primRandom = function(b) {
|
||||
var n1 = interp.arg(b, 0);
|
||||
var n2 = interp.arg(b, 1);
|
||||
var low = (n1 <= n2) ? n1 : n2;
|
||||
var hi = (n1 <= n2) ? n2 : n1;
|
||||
if(low == hi) return low;
|
||||
var low = n1 <= n2 ? n1 : n2;
|
||||
var hi = n1 <= n2 ? n2 : n1;
|
||||
if (low == hi) return low;
|
||||
// if both low and hi are ints, truncate the result to an int
|
||||
if ((Math.floor(low) == low) && (Math.floor(hi) == hi)) {
|
||||
return low + Math.floor(Math.random() * ((hi + 1) - low));
|
||||
if (Math.floor(low) == low && Math.floor(hi) == hi) {
|
||||
return low + Math.floor(Math.random() * (hi + 1 - low));
|
||||
}
|
||||
return (Math.random() * (hi - low)) + low;
|
||||
return Math.random() * (hi - low) + low;
|
||||
}
|
||||
|
||||
Primitives.prototype.primLetterOf = function(b) {
|
||||
var s = interp.arg(b, 1);
|
||||
var i = interp.arg(b, 0) - 1;
|
||||
if ((i < 0) || (i >= s.length)) return "";
|
||||
if (i < 0 || i >= s.length) return "";
|
||||
return s.charAt(i);
|
||||
}
|
||||
|
||||
|
@ -90,12 +90,12 @@ Primitives.prototype.primMathFunction = function(b) {
|
|||
switch(op) {
|
||||
case "abs": return Math.abs(n);
|
||||
case "sqrt": return Math.sqrt(n);
|
||||
case "sin": return Math.sin((Math.PI * n) / 180);
|
||||
case "cos": return Math.cos((Math.PI * n) / 180);
|
||||
case "tan": return Math.tan((Math.PI * n) / 180);
|
||||
case "asin": return (Math.asin(n) * 180) / Math.PI;
|
||||
case "acos": return (Math.acos(n) * 180) / Math.PI;
|
||||
case "atan": return (Math.atan(n) * 180) / Math.PI;
|
||||
case "sin": return Math.sin(n * Math.PI / 180);
|
||||
case "cos": return Math.cos(n * Math.PI / 180);
|
||||
case "tan": return Math.tan(n * Math.PI / 180);
|
||||
case "asin": return Math.asin(n) * 180 / Math.PI;
|
||||
case "acos": return Math.acos(n) * 180 / Math.PI;
|
||||
case "atan": return Math.atan(n) * 180 / Math.PI;
|
||||
case "ln": return Math.log(n);
|
||||
case "log": return Math.log(n) / Math.LN10;
|
||||
case "e ^": return Math.exp(n);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var SensingPrims = function() {}
|
||||
var SensingPrims = function() {};
|
||||
|
||||
SensingPrims.prototype.addPrimsTo = function(primTable) {
|
||||
primTable['touching:'] = this.primTouching;
|
||||
|
@ -32,7 +32,7 @@ SensingPrims.prototype.addPrimsTo = function(primTable) {
|
|||
|
||||
primTable['timeAndDate'] = function(b){ return runtime.getTimeString(interp.arg(b, 0)); };
|
||||
primTable['timestamp'] = this.primTimestamp;
|
||||
}
|
||||
};
|
||||
|
||||
SensingPrims.prototype.primTouching = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
|
@ -51,7 +51,7 @@ SensingPrims.prototype.primTouching = function(b) {
|
|||
if (s2 == null || !s2.visible) return false;
|
||||
|
||||
return spriteHitTest(s, s2);
|
||||
}
|
||||
};
|
||||
|
||||
SensingPrims.prototype.primTouchingColor = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
|
@ -60,7 +60,7 @@ SensingPrims.prototype.primTouchingColor = function(b) {
|
|||
var color = interp.arg(b, 0);
|
||||
|
||||
return stageColorHitTest(s, color);
|
||||
}
|
||||
};
|
||||
|
||||
SensingPrims.prototype.primColorTouchingColor = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
|
@ -70,7 +70,7 @@ SensingPrims.prototype.primColorTouchingColor = function(b) {
|
|||
var stageColor = interp.arg(b, 1);
|
||||
|
||||
return stageColorByColorHitTest(s, myColor, stageColor);
|
||||
}
|
||||
};
|
||||
|
||||
var spriteHitTest = function(a, b) {
|
||||
var hitCanvas = document.createElement('canvas');
|
||||
|
@ -91,7 +91,7 @@ var spriteHitTest = function(a, b) {
|
|||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
var stageColorHitTest = function(target, color) {
|
||||
var r, g, b;
|
||||
|
@ -123,7 +123,7 @@ var stageColorHitTest = function(target, color) {
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
var stageColorByColorHitTest = function(target, myColor, otherColor) {
|
||||
var threshold_acceptable = function(a, b, c, x, y, z) {
|
||||
|
@ -134,7 +134,7 @@ var stageColorByColorHitTest = function(target, myColor, otherColor) {
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
var targetCanvas = document.createElement('canvas');
|
||||
targetCanvas.width = 480;
|
||||
targetCanvas.height = 360;
|
||||
|
@ -159,20 +159,20 @@ var stageColorByColorHitTest = function(target, myColor, otherColor) {
|
|||
hitCanvas.height = 360;
|
||||
var hitCtx = hitCanvas.getContext('2d');
|
||||
$.each(runtime.sprites, function(i, sprite) {
|
||||
if (sprite != target)
|
||||
if (sprite != target) {
|
||||
sprite.stamp(hitCtx, 100);
|
||||
}
|
||||
});
|
||||
|
||||
var hitData = hitCtx.getImageData(0, 0, hitCanvas.width, hitCanvas.height).data;
|
||||
var pxCount = targetData.length;
|
||||
for (var i = 0; i < pxCount; i += 4) {
|
||||
if (threshold_acceptable(targetData[i], targetData[i+1], targetData[i+2], mr, mg, mb)
|
||||
&& threshold_acceptable(hitData[i], hitData[i+1], hitData[i+2], or, og, ob)) {
|
||||
if (threshold_acceptable(targetData[i], targetData[i+1], targetData[i+2], mr, mg, mb) && threshold_acceptable(hitData[i], hitData[i+1], hitData[i+2], or, og, ob)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
SensingPrims.prototype.primKeyPressed = function(b) {
|
||||
var key = interp.arg(b, 0);
|
||||
|
@ -184,7 +184,7 @@ SensingPrims.prototype.primKeyPressed = function(b) {
|
|||
if (key == "down arrow") ch = 40;
|
||||
if (key == "space") ch = 32;
|
||||
return (typeof(runtime.keysDown[ch]) != 'undefined');
|
||||
}
|
||||
};
|
||||
|
||||
SensingPrims.prototype.primDistanceTo = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
|
@ -193,7 +193,7 @@ SensingPrims.prototype.primDistanceTo = function(b) {
|
|||
var dx = p.x - s.scratchX;
|
||||
var dy = p.y - s.scratchY;
|
||||
return Math.sqrt((dx * dx) + (dy * dy));
|
||||
}
|
||||
};
|
||||
|
||||
SensingPrims.prototype.primGetAttribute = function(b) {
|
||||
var attr = interp.arg(b, 0);
|
||||
|
@ -207,7 +207,7 @@ SensingPrims.prototype.primGetAttribute = function(b) {
|
|||
if (attr == 'size') return targetSprite.getSize();
|
||||
if (attr == 'volume') return targetSprite.volume;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
SensingPrims.prototype.primTimeDate = function(b) {
|
||||
var dt = interp.arg(b, 0);
|
||||
|
@ -220,13 +220,16 @@ SensingPrims.prototype.primTimeDate = function(b) {
|
|||
if (dt == 'minute') return now.getMinutes();
|
||||
if (dt == 'second') return now.getSeconds();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
SensingPrims.prototype.primTimestamp = function(b) {
|
||||
var now = new Date(), epoch = new Date(2000,0,1), dst = now.getTimezoneOffset() - epoch.getTimezoneOffset(), msSince = now.getTime() - epoch.getTime();
|
||||
var now = new Date();
|
||||
var epoch = new Date(2000, 0, 1);
|
||||
var dst = now.getTimezoneOffset() - epoch.getTimezoneOffset();
|
||||
var msSince = now.getTime() - epoch.getTime();
|
||||
msSince += (now.getTimezoneOffset() - dst) * 60000;
|
||||
return msSince / 86400000;
|
||||
}
|
||||
};
|
||||
|
||||
// Helpers
|
||||
SensingPrims.prototype.mouseOrSpritePosition = function(arg) {
|
||||
|
@ -239,4 +242,4 @@ SensingPrims.prototype.mouseOrSpritePosition = function(arg) {
|
|||
return new Point(s.scratchX, s.scratchY);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var SoundPrims = function() {}
|
||||
var SoundPrims = function() {};
|
||||
|
||||
SoundPrims.prototype.addPrimsTo = function(primTable) {
|
||||
primTable['playSound:'] = this.primPlaySound;
|
||||
|
@ -34,7 +34,7 @@ SoundPrims.prototype.addPrimsTo = function(primTable) {
|
|||
primTable['changeTempoBy:'] = function(b) { runtime.stage.data.tempoBPM = runtime.stage.data.tempoBPM + interp.arg(b, 0); };
|
||||
primTable['setTempoTo:'] = function(b) { runtime.stage.data.tempoBPM = interp.arg(b, 0); };
|
||||
primTable['tempo'] = function(b) { return runtime.stage.data.tempoBPM; };
|
||||
}
|
||||
};
|
||||
|
||||
var playSound = function(snd) {
|
||||
if (snd.source) {
|
||||
|
@ -64,7 +64,7 @@ var playSound = function(snd) {
|
|||
runtime.audioPlaying.push(snd);
|
||||
snd.source.noteOn(0);
|
||||
return snd.source;
|
||||
}
|
||||
};
|
||||
|
||||
var playDrum = function(drum, secs, client) {
|
||||
var player = SoundBank.getDrumPlayer(drum, secs);
|
||||
|
@ -83,7 +83,7 @@ var playDrum = function(drum, secs, client) {
|
|||
}
|
||||
window.setTimeout(source.finished, secs * 1000);
|
||||
return player;
|
||||
}
|
||||
};
|
||||
|
||||
var playNote = function(instrument, midiKey, secs, client) {
|
||||
var player = SoundBank.getNotePlayer(instrument, midiKey);
|
||||
|
@ -101,7 +101,7 @@ var playNote = function(instrument, midiKey, secs, client) {
|
|||
}
|
||||
window.setTimeout(source.finished, secs * 1000);
|
||||
return player;
|
||||
}
|
||||
};
|
||||
|
||||
var stopAllSounds = function() {
|
||||
var oldPlaying = runtime.audioPlaying;
|
||||
|
@ -121,14 +121,14 @@ var stopAllSounds = function() {
|
|||
oldPlaying[s].finished();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SoundPrims.prototype.primPlaySound = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s == null) return;
|
||||
var snd = s.soundNamed(interp.arg(b, 0));
|
||||
if (snd != null) playSound(snd);
|
||||
}
|
||||
};
|
||||
|
||||
SoundPrims.prototype.primPlaySoundUntilDone = function(b) {
|
||||
var activeThread = interp.activeThread;
|
||||
|
@ -145,11 +145,11 @@ SoundPrims.prototype.primPlaySoundUntilDone = function(b) {
|
|||
} else {
|
||||
interp.yield = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var beatsToSeconds = function(beats) {
|
||||
return (beats * 60) / runtime.stage.data.tempoBPM;
|
||||
}
|
||||
return beats * 60 / runtime.stage.data.tempoBPM;
|
||||
};
|
||||
|
||||
SoundPrims.prototype.primPlayNote = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
|
@ -162,7 +162,7 @@ SoundPrims.prototype.primPlayNote = function(b) {
|
|||
} else {
|
||||
interp.checkTimer();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SoundPrims.prototype.primPlayDrum = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
|
@ -175,7 +175,7 @@ SoundPrims.prototype.primPlayDrum = function(b) {
|
|||
} else {
|
||||
interp.checkTimer();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SoundPrims.prototype.primPlayRest = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
|
@ -186,28 +186,28 @@ SoundPrims.prototype.primPlayRest = function(b) {
|
|||
} else {
|
||||
interp.checkTimer();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SoundPrims.prototype.primSetInstrument = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) s.instrument = interp.arg(b, 0);
|
||||
}
|
||||
};
|
||||
|
||||
SoundPrims.prototype.primStopAllSounds = function(b) {
|
||||
stopAllSounds();
|
||||
}
|
||||
};
|
||||
|
||||
SoundPrims.prototype.primChangeVolume = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) s.volume += interp.arg(b, 0);
|
||||
}
|
||||
};
|
||||
|
||||
SoundPrims.prototype.primSetVolume = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s != null) s.volume = interp.arg(b, 0);
|
||||
}
|
||||
};
|
||||
|
||||
SoundPrims.prototype.primVolume = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
return (s != null) ? s.volume : 0;
|
||||
}
|
||||
return s != null ? s.volume : 0;
|
||||
};
|
||||
|
|
|
@ -34,7 +34,7 @@ VarListPrims.prototype.addPrimsTo = function(primTable) {
|
|||
primTable['lineCountOfList:'] = this.primListLength;
|
||||
primTable['getLine:ofList:'] = this.primListGetLine;
|
||||
primTable['list:contains:'] = this.primListContains;
|
||||
}
|
||||
};
|
||||
|
||||
// Variable primitive implementations
|
||||
|
||||
|
@ -42,21 +42,23 @@ VarListPrims.prototype.primReadVar = function(b) {
|
|||
var s = interp.targetSprite();
|
||||
if (s == null) return;
|
||||
var targetVar = interp.arg(b, 0);
|
||||
if (targetVar in s.variables)
|
||||
if (targetVar in s.variables) {
|
||||
return s.variables[targetVar];
|
||||
else if (targetVar in runtime.stage.variables)
|
||||
} else if (targetVar in runtime.stage.variables) {
|
||||
return runtime.stage.variables[targetVar];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
VarListPrims.prototype.primSetVar = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
if (s == null) return;
|
||||
var targetVar = interp.arg(b, 0);
|
||||
if (targetVar in s.variables)
|
||||
if (targetVar in s.variables) {
|
||||
s.variables[targetVar] = interp.arg(b, 1);
|
||||
else if (targetVar in runtime.stage.variables)
|
||||
} else if (targetVar in runtime.stage.variables) {
|
||||
runtime.stage.variables[targetVar] = interp.arg(b, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
VarListPrims.prototype.primChangeVar = function(b) {
|
||||
var s = interp.targetSprite();
|
||||
|
@ -69,7 +71,7 @@ VarListPrims.prototype.primChangeVar = function(b) {
|
|||
runtime.stage.variables[targetVar] = parseFloat(runtime.stage.variables[targetVar]);
|
||||
runtime.stage.variables[targetVar] += interp.arg(b, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
VarListPrims.prototype.primHideVar = function(b) {
|
||||
var targetVar = interp.arg(b, 0);
|
||||
|
@ -79,7 +81,7 @@ VarListPrims.prototype.primHideVar = function(b) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
VarListPrims.prototype.primShowVar = function(b) {
|
||||
var targetVar = interp.arg(b, 0);
|
||||
|
@ -89,7 +91,7 @@ VarListPrims.prototype.primShowVar = function(b) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// List primitive implementations
|
||||
|
||||
|
@ -102,20 +104,20 @@ var findList = function(targetSprite, listName) {
|
|||
return runtime.stage.lists[listName].contents;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
VarListPrims.prototype.primReadList = function(b) {
|
||||
var list = findList(interp.targetSprite(), interp.arg(b, 0));
|
||||
if (list) {
|
||||
var allOne = list.map(function(val){return val.length}).reduce(function(old,val){return old+val},0)===list.length;
|
||||
return list.join(allOne?'':' ');
|
||||
var allOne = list.map(function(val) { return val.length; }).reduce(function(old,val) { return old + val; }, 0) === list.length;
|
||||
return list.join(allOne ? '' : ' ');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
VarListPrims.prototype.primListAppend = function(b) {
|
||||
var list = findList(interp.targetSprite(), interp.arg(b, 1));
|
||||
if (list) list.push(interp.arg(b, 0));
|
||||
}
|
||||
};
|
||||
|
||||
VarListPrims.prototype.primListDeleteLine = function(b) {
|
||||
var list = findList(interp.targetSprite(), interp.arg(b, 1));
|
||||
|
@ -124,7 +126,7 @@ VarListPrims.prototype.primListDeleteLine = function(b) {
|
|||
if (line == 'all' || list.length == 0) list.length = 0;
|
||||
else if (line == 'last') list.splice(list.length - 1, 1);
|
||||
else if (parseInt(line) - 1 in list) list.splice(parseInt(line) - 1, 1);
|
||||
}
|
||||
};
|
||||
|
||||
VarListPrims.prototype.primListInsertAt = function(b) {
|
||||
var list = findList(interp.targetSprite(), interp.arg(b, 2));
|
||||
|
@ -138,7 +140,7 @@ VarListPrims.prototype.primListInsertAt = function(b) {
|
|||
if (position > list.length) return;
|
||||
|
||||
list.splice(position, 0, newItem);
|
||||
}
|
||||
};
|
||||
|
||||
VarListPrims.prototype.primListSetLine = function(b) {
|
||||
var list = findList(interp.targetSprite(), interp.arg(b, 1));
|
||||
|
@ -149,16 +151,17 @@ VarListPrims.prototype.primListSetLine = function(b) {
|
|||
if (position == 'last') position = list.length - 1;
|
||||
else if (position == 'random') position = Math.floor(Math.random() * list.length);
|
||||
else position = parseInt(position) - 1;
|
||||
|
||||
if (position > list.length - 1) return;
|
||||
|
||||
list[position] = newItem;
|
||||
}
|
||||
};
|
||||
|
||||
VarListPrims.prototype.primListLength = function(b) {
|
||||
var list = findList(interp.targetSprite(), interp.arg(b, 0));
|
||||
if (!list) return 0;
|
||||
return list.length;
|
||||
}
|
||||
};
|
||||
|
||||
VarListPrims.prototype.primListGetLine = function(b) {
|
||||
var list = findList(interp.targetSprite(), interp.arg(b, 1));
|
||||
|
@ -169,7 +172,7 @@ VarListPrims.prototype.primListGetLine = function(b) {
|
|||
else if (line == 'last') line = list.length;
|
||||
else if (list.length < line) return 0;
|
||||
return list[line - 1];
|
||||
}
|
||||
};
|
||||
|
||||
VarListPrims.prototype.primListContains = function(b) {
|
||||
var list = findList(interp.targetSprite(), interp.arg(b, 0));
|
||||
|
@ -177,4 +180,4 @@ VarListPrims.prototype.primListContains = function(b) {
|
|||
var searchItem = interp.arg(b, 1);
|
||||
if (parseFloat(searchItem) == searchItem) searchItem = parseFloat(searchItem);
|
||||
return $.inArray(searchItem, list) > -1;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -65,11 +65,11 @@ var NotePlayer = function(wavFileData, originalPitch, loopStart, loopEnd, env) {
|
|||
if (env) {
|
||||
this.attackEnd = env[0] * 44.100;
|
||||
if (this.attackEnd > 0) this.attackRate = Math.pow(33000, 1 / this.attackEnd);
|
||||
this.holdEnd = this.attackEnd + (env[1] * 44.100);
|
||||
this.holdEnd = this.attackEnd + env[1] * 44.100;
|
||||
var decayCount = env[2] * 44100;
|
||||
this.decayRate = (decayCount == 0) ? 1 : Math.pow(33000, -1 / decayCount);
|
||||
this.decayRate = decayCount == 0 ? 1 : Math.pow(33000, -1 / decayCount);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
NotePlayer.prototype = Object.create(SoundDecoder.prototype);
|
||||
NotePlayer.prototype.constructor = NotePlayer;
|
||||
|
@ -79,14 +79,14 @@ NotePlayer.prototype.setNoteAndDuration = function(midiKey, secs) {
|
|||
var pitch = 440 * Math.pow(2, (midiKey - 69) / 12); // midi key 69 is A (440 Hz)
|
||||
this.stepSize = pitch / (2 * this.originalPitch); // adjust for original sampling rate of 22050
|
||||
this.setDuration(secs);
|
||||
}
|
||||
};
|
||||
|
||||
NotePlayer.prototype.setDuration = function(secs) {
|
||||
this.samplesSinceStart = 0;
|
||||
this.samplesRemaining = 44100 * secs;
|
||||
if (!this.isLooped) this.samplesRemaining = Math.min(this.samplesRemaining, this.endOffset / this.stepSize);
|
||||
this.envelopeValue = (this.attackEnd > 0) ? 1 / 33000 : 1;
|
||||
}
|
||||
this.envelopeValue = this.attackEnd > 0 ? 1 / 33000 : 1;
|
||||
};
|
||||
|
||||
NotePlayer.prototype.interpolatedSample = function() {
|
||||
if (this.samplesRemaining-- <= 0) { this.noteFinished(); return 0; }
|
||||
|
@ -99,11 +99,11 @@ NotePlayer.prototype.interpolatedSample = function() {
|
|||
var frac = this.index - i;
|
||||
var curr = this.rawSample(i);
|
||||
var next = this.rawSample(i + 1);
|
||||
var sample = (curr + (frac * (next - curr))) / 100000; // xxx 32000; attenuate...
|
||||
var sample = (curr + frac * (next - curr)) / 100000; // xxx 32000; attenuate...
|
||||
if (this.samplesRemaining < 1000) sample *= (this.samplesRemaining / 1000.0); // relaase phease
|
||||
this.updateEnvelope();
|
||||
return this.envelopeValue * sample;
|
||||
}
|
||||
};
|
||||
|
||||
NotePlayer.prototype.rawSample = function(sampleIndex) {
|
||||
if (sampleIndex >= this.endOffset) {
|
||||
|
@ -112,8 +112,8 @@ NotePlayer.prototype.rawSample = function(sampleIndex) {
|
|||
}
|
||||
var byteIndex = 2 * sampleIndex;
|
||||
var result = (this.soundData[byteIndex + 1] << 8) + this.soundData[byteIndex];
|
||||
return (result <= 32767) ? result : result - 65536;
|
||||
}
|
||||
return result <= 32767 ? result : result - 65536;
|
||||
};
|
||||
|
||||
NotePlayer.prototype.updateEnvelope = function() {
|
||||
// Compute envelopeValue for the current sample.
|
||||
|
@ -125,4 +125,4 @@ NotePlayer.prototype.updateEnvelope = function() {
|
|||
} else if (this.samplesSinceStart > this.holdEnd) {
|
||||
if (this.decayRate < 1) this.envelopeValue *= this.decayRate;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -178,24 +178,24 @@ SoundBank.getNotePlayer = function(instNum, midiKey) {
|
|||
// Return a NotePlayer for the given Scratch 2.0 instrument number (1..21)
|
||||
// and MIDI key (0..127). If the instrument is out of range, use 1.
|
||||
var r = SoundBank.getNoteRecord(instNum - 1, midiKey);
|
||||
var env = (r.length > 5) ? r[5] : null;
|
||||
var env = r.length > 5 ? r[5] : null;
|
||||
return new NotePlayer(Instr.samples[r[1]], SoundBank.pitchForKey(r[2]), r[3], r[4], env);
|
||||
}
|
||||
};
|
||||
|
||||
SoundBank.getNoteRecord = function(instNum, midiKey) {
|
||||
// Get a note record for the given instrument number.
|
||||
if ((instNum < 0) || (instNum >= SoundBank.instruments.length)) instNum = 0;
|
||||
if (instNum < 0 || instNum >= SoundBank.instruments.length) instNum = 0;
|
||||
var keyRanges = SoundBank.instruments[instNum];
|
||||
for (var r = 0; r < keyRanges.length; r++) {
|
||||
var topOfKeyRange = keyRanges[r][0];
|
||||
if (midiKey <= topOfKeyRange) return keyRanges[r];
|
||||
}
|
||||
return keyRanges[keyRanges.length - 1]; // return the note record for the top key range.
|
||||
}
|
||||
};
|
||||
|
||||
SoundBank.pitchForKey = function(midiKey) {
|
||||
return 440 * Math.pow(2, (midiKey - 69) / 12); // midi key 69 is A=440 Hz
|
||||
}
|
||||
};
|
||||
|
||||
SoundBank.getDrumPlayer = function(drumNum, secs) {
|
||||
// Return a NotePlayer for the given drum number.
|
||||
|
@ -210,6 +210,4 @@ SoundBank.getDrumPlayer = function(drumNum, secs) {
|
|||
var player = new NotePlayer(Instr.samples[entry[0]], SoundBank.pitchForKey(60), loopStart, loopEnd, env);
|
||||
player.setNoteAndDuration(60 + entry[1], 0);
|
||||
return player;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -61,12 +61,12 @@ var SoundDecoder = function(wavFileData) {
|
|||
if (info.bitsPerSample == 16) this.getSample = this.getSample16Uncompressed;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SoundDecoder.prototype.noteFinished = function() {
|
||||
// Called by subclasses to force ending condition to be true in writeSampleData()
|
||||
this.bytePosition = this.endOffset;
|
||||
}
|
||||
};
|
||||
|
||||
// Used for Notes and Drums - Web Audio API ScriptProcessorNodes use this
|
||||
// as a callback function to fill the buffers with sample data.
|
||||
|
@ -78,7 +78,7 @@ SoundDecoder.prototype.writeSampleData = function(evt) {
|
|||
var n = this.interpolatedSample();
|
||||
output[i] = n;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// For pre-caching the samples of WAV sounds
|
||||
// Return a full list of samples generated by the decoder.
|
||||
|
@ -90,7 +90,7 @@ SoundDecoder.prototype.getAllSamples = function() {
|
|||
smp = this.interpolatedSample();
|
||||
}
|
||||
return samples;
|
||||
}
|
||||
};
|
||||
|
||||
// Provide the next sample for the buffer
|
||||
SoundDecoder.prototype.interpolatedSample = function() {
|
||||
|
@ -101,11 +101,9 @@ SoundDecoder.prototype.interpolatedSample = function() {
|
|||
this.fraction -= 1.0;
|
||||
}
|
||||
if (this.nextSample == null) { return null; }
|
||||
var out = (this.fraction == 0) ?
|
||||
this.thisSample :
|
||||
this.thisSample + (this.fraction * (this.nextSample - this.thisSample));
|
||||
return (out) / 32768.0;
|
||||
}
|
||||
var out = this.fraction == 0 ? this.thisSample : this.thisSample + this.fraction * (this.nextSample - this.thisSample);
|
||||
return out / 32768.0;
|
||||
};
|
||||
|
||||
// 16-bit samples, big-endian
|
||||
SoundDecoder.prototype.getSample16Uncompressed = function() {
|
||||
|
@ -119,13 +117,13 @@ SoundDecoder.prototype.getSample16Uncompressed = function() {
|
|||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// 8-bit samples, uncompressed
|
||||
SoundDecoder.prototype.getSample8Uncompressed = function() {
|
||||
if (this.bytePosition >= this.info.sampleDataSize) return null;
|
||||
return (this.soundData[this.bytePosition++] - 128) << 8;
|
||||
}
|
||||
};
|
||||
|
||||
/*SoundDecoder.prototype.updateVolume = function() {
|
||||
if (this.client == null) {
|
||||
|
@ -154,8 +152,8 @@ SoundDecoder.prototype.getSampleADPCM = function() {
|
|||
// Note: Handles only one channel, 4-bits/sample.
|
||||
var step = 0, code = 0, delta = 0;
|
||||
|
||||
if (((this.bytePosition % this.adpcmBlockSize) == 0) && (this.lastByte < 0)) { // read block header
|
||||
if (this.bytePosition > (this.info.sampleDataSize - 4)) return null;
|
||||
if (this.bytePosition % this.adpcmBlockSize == 0 && this.lastByte < 0) { // read block header
|
||||
if (this.bytePosition > this.info.sampleDataSize - 4) return null;
|
||||
this.sample = (this.soundData[this.bytePosition + 1] << 8) + this.soundData[this.bytePosition];
|
||||
if (this.sample > 32767) this.sample -= 65536;
|
||||
this.index = this.soundData[this.bytePosition + 2];
|
||||
|
@ -184,7 +182,7 @@ SoundDecoder.prototype.getSampleADPCM = function() {
|
|||
if (this.index > 88) this.index = 88;
|
||||
if (this.index < 0) this.index = 0;
|
||||
// compute and output sample
|
||||
this.sample += ((code & 8) ? -delta : delta);
|
||||
this.sample += code & 8 ? -delta : delta;
|
||||
if (this.sample > 32767) this.sample = 32767;
|
||||
if (this.sample < -32768) this.sample = -32768;
|
||||
return this.sample;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
var WAVFile = function() {};
|
||||
|
||||
|
||||
WAVFile.decode = function(waveData) {
|
||||
// Decode the given WAV file data and return an Object with the format and sample data.
|
||||
var result = {};
|
||||
|
@ -75,8 +74,7 @@ WAVFile.decode = function(waveData) {
|
|||
return;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
WAVFile.extractChunk = function(desiredType, data) {
|
||||
// Return the contents of the first chunk of the given type or an empty OffsetBuffer if it is not found.
|
||||
|
@ -93,8 +91,7 @@ WAVFile.extractChunk = function(desiredType, data) {
|
|||
}
|
||||
}
|
||||
return new OffsetBuffer(new ArrayBuffer());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
WAVFile.dataChunkStartAndSize = function(data) {
|
||||
// Return an array with the starting offset and size of the first chunk of the given type.
|
||||
|
@ -110,4 +107,4 @@ WAVFile.dataChunkStartAndSize = function(data) {
|
|||
}
|
||||
}
|
||||
return [0, 0]; // chunk not found; bad wave file
|
||||
}
|
||||
};
|
||||
|
|
|
@ -29,8 +29,8 @@ Color.fromHSV = function(h, s, v) {
|
|||
var i = Math.floor(h / 60);
|
||||
var f = (h / 60) - i;
|
||||
var p = v * (1 - s);
|
||||
var q = v * (1 - (s * f));
|
||||
var t = v * (1 - (s * (1 - f)));
|
||||
var q = v * (1 - s * f);
|
||||
var t = v * (1 - s * (1 - f));
|
||||
if (i == 0) { r = v; g = t; b = p; }
|
||||
else if (i == 1) { r = q; g = v; b = p; }
|
||||
else if (i == 2) { r = p; g = v; b = t; }
|
||||
|
@ -41,7 +41,7 @@ Color.fromHSV = function(h, s, v) {
|
|||
g = Math.floor(g * 255);
|
||||
b = Math.floor(b * 255);
|
||||
return (r << 16) | (g << 8) | b;
|
||||
}
|
||||
};
|
||||
|
||||
Color.rgb2hsv = function(rgb) {
|
||||
var h, s, v, x, f, i;
|
||||
|
@ -51,18 +51,18 @@ Color.rgb2hsv = function(rgb) {
|
|||
x = Math.min(Math.min(r, g), b);
|
||||
v = Math.max(Math.max(r, g), b);
|
||||
if (x == v) return [0, 0, v]; // gray; hue arbitrarily reported as zero
|
||||
f = (r == x) ? g - b : ((g == x) ? b - r : r - g);
|
||||
i = (r == x) ? 3 : ((g == x) ? 5 : 1);
|
||||
h = ((i - (f / (v - x))) * 60) % 360;
|
||||
f = r == x ? g - b : g == x ? b - r : r - g;
|
||||
i = r == x ? 3 : g == x ? 5 : 1;
|
||||
h = ((i - f / (v - x)) * 60) % 360;
|
||||
s = (v - x) / v;
|
||||
return [h, s, v];
|
||||
}
|
||||
};
|
||||
|
||||
Color.scaleBrightness = function(rgb, scale) {
|
||||
var hsv = Color.rgb2hsv(rgb);
|
||||
scale = Math.max(0, Math.min(scale, 1));
|
||||
return Color.fromHSV(hsv[0], hsv[1], scale * hsv[2]);
|
||||
}
|
||||
};
|
||||
|
||||
Color.mixRGB = function(rgb1, rgb2, fraction) {
|
||||
// Mix rgb1 with rgb2. 0 gives all rgb1, 1 gives rbg2, .5 mixes them 50/50.
|
||||
|
@ -78,7 +78,7 @@ Color.mixRGB = function(rgb1, rgb2, fraction) {
|
|||
var g = ((fraction * g2) + ((1.0 - fraction) * g1)) & 255;
|
||||
var b = ((fraction * b2) + ((1.0 - fraction) * b1)) & 255;
|
||||
return (r << 16) | (g << 8) | b;
|
||||
}
|
||||
};
|
||||
|
||||
Color.random = function() {
|
||||
// return a random color
|
||||
|
@ -86,4 +86,4 @@ Color.random = function() {
|
|||
var s = 0.7 + (0.3 * Math.random());
|
||||
var v = 0.6 + (0.4 * Math.random());
|
||||
return Color.fromHSV(h, s, v);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -19,63 +19,63 @@
|
|||
var OffsetBuffer = function(data) {
|
||||
this.offset = 0;
|
||||
this.ab = data;
|
||||
}
|
||||
};
|
||||
|
||||
// Read various datatypes from the ArrayBuffer, seeking the offset.
|
||||
OffsetBuffer.prototype.readString = function(length) {
|
||||
var str = this.ab2str(this.ab.slice(this.offset, this.offset + length));
|
||||
this.offset += length;
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
OffsetBuffer.prototype.readInt = function() {
|
||||
var num = this.ab2int(this.ab.slice(this.offset, this.offset + 4));
|
||||
this.offset += 4;
|
||||
return num;
|
||||
}
|
||||
};
|
||||
|
||||
OffsetBuffer.prototype.readUint = function() {
|
||||
var num = this.ab2uint(this.ab.slice(this.offset, this.offset + 4));
|
||||
this.offset += 4;
|
||||
return num;
|
||||
}
|
||||
};
|
||||
|
||||
OffsetBuffer.prototype.readShort = function() {
|
||||
var num = this.ab2short(this.ab.slice(this.offset, this.offset + 2));
|
||||
this.offset += 2;
|
||||
return num;
|
||||
}
|
||||
};
|
||||
|
||||
OffsetBuffer.prototype.readBytes = function(length) {
|
||||
var bytes = this.ab.slice(this.offset, this.offset + length);
|
||||
this.offset += length;
|
||||
return bytes;
|
||||
}
|
||||
};
|
||||
|
||||
// Length of the internal buffer
|
||||
OffsetBuffer.prototype.getLength = function() {
|
||||
return this.ab.byteLength;
|
||||
}
|
||||
};
|
||||
|
||||
// Number of bytes remaining from the current offset
|
||||
OffsetBuffer.prototype.bytesAvailable = function() {
|
||||
return (this.getLength() - this.offset);
|
||||
}
|
||||
return this.getLength() - this.offset;
|
||||
};
|
||||
|
||||
// ArrayBuffer -> JS type conversion methods
|
||||
OffsetBuffer.prototype.ab2str = function(buf) {
|
||||
return String.fromCharCode.apply(null, new Uint8Array(buf));
|
||||
}
|
||||
};
|
||||
|
||||
// These create Javascript Numbers
|
||||
OffsetBuffer.prototype.ab2int = function(buf) {
|
||||
return new Int32Array(buf)[0];
|
||||
}
|
||||
};
|
||||
|
||||
OffsetBuffer.prototype.ab2uint = function(buf) {
|
||||
return new Uint32Array(buf)[0];
|
||||
}
|
||||
};
|
||||
|
||||
OffsetBuffer.prototype.ab2short = function(buf) {
|
||||
return new Int16Array(buf)[0];
|
||||
}
|
||||
};
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
var Point = function(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
};
|
||||
|
||||
var Rectangle = function(x, y, width, height) {
|
||||
this.x = x;
|
||||
|
@ -27,10 +27,8 @@ var Rectangle = function(x, y, width, height) {
|
|||
this.right = x + width;
|
||||
this.top = y;
|
||||
this.bottom = y + height;
|
||||
}
|
||||
};
|
||||
|
||||
Rectangle.prototype.intersects = function(other) {
|
||||
return !(this.left > other.right ||
|
||||
this.right < other.left ||
|
||||
this.top > other.bottom ||
|
||||
this.bottom < other.top);
|
||||
}
|
||||
return !(this.left > other.right || this.right < other.left || this.top > other.bottom || this.bottom < other.top);
|
||||
};
|
||||
|
|
|
@ -21,40 +21,40 @@ var Timer = function() {
|
|||
var trials = [];
|
||||
var last_trial = 0;
|
||||
var start_time = 0;
|
||||
}
|
||||
};
|
||||
|
||||
Timer.prototype.time = function() {
|
||||
return (new Date()).getTime();
|
||||
}
|
||||
return Date.now();
|
||||
};
|
||||
|
||||
Timer.prototype.start = function() {
|
||||
start_time = this.time();
|
||||
}
|
||||
};
|
||||
|
||||
Timer.prototype.stop = function() {
|
||||
end = this.time();
|
||||
last_trial = end - start_time;
|
||||
trials.push(last_trial);
|
||||
}
|
||||
};
|
||||
|
||||
Timer.prototype.count = function() {
|
||||
return trials.length;
|
||||
}
|
||||
};
|
||||
|
||||
Timer.prototype.average = function() {
|
||||
sum = 0;
|
||||
for(i = 0; i < this.count(); i++) {
|
||||
for (i = 0; i < this.count(); i++) {
|
||||
sum += trials[i];
|
||||
}
|
||||
return sum / this.count();
|
||||
}
|
||||
};
|
||||
|
||||
Timer.prototype.print = function(element) {
|
||||
text = "Trial: " + last_trial + "ms" +
|
||||
"<br />\nTrials: " + this.count() + ", Avg: " + this.average() + "ms";
|
||||
if(element) {
|
||||
if (element) {
|
||||
$(element).html(text);
|
||||
} else {
|
||||
console.log(text);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Reference in a new issue