From 1a72b01b31be361da7d0a88711ae8286dd90b57a Mon Sep 17 00:00:00 2001 From: Nathan Dinsmore <nfdins@gmail.com> Date: Fri, 1 Nov 2013 22:44:51 -0400 Subject: [PATCH] Formatting and indentation fixes --- compare.html | 201 +++++++++++++++-------------- js/IO.js | 48 ++++--- js/Interpreter.js | 100 +++++++------- js/Reporter.js | 19 +-- js/Runtime.js | 72 +++++------ js/Scratch.js | 36 +++--- js/Sprite.js | 168 ++++++++++++------------ js/Stage.js | 25 ++-- js/primitives/LooksPrims.js | 64 ++++----- js/primitives/MotionAndPenPrims.js | 143 ++++++++++---------- js/primitives/Primitives.js | 64 ++++----- js/primitives/SensingPrims.js | 75 +++++------ js/primitives/SoundPrims.js | 46 +++---- js/primitives/VarListPrims.js | 53 ++++---- js/sound/NotePlayer.js | 22 ++-- js/sound/SoundBank.js | 14 +- js/sound/SoundDecoder.js | 38 +++--- js/sound/WAVFile.js | 17 +-- js/util/Color.js | 116 ++++++++--------- js/util/OffsetBuffer.js | 26 ++-- js/util/Rectangle.js | 12 +- js/util/Timer.js | 22 ++-- 22 files changed, 690 insertions(+), 691 deletions(-) diff --git a/compare.html b/compare.html index 6931714..1e89b26 100644 --- a/compare.html +++ b/compare.html @@ -4,112 +4,113 @@ header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past ?> <!DOCTYPE html> <html> - <head> - <title>Scratch HTML5 vs. Flash</title> - <meta charset="utf-8"> - <style type="text/css"> - body { - background: #222; - color: #fff; - margin: 0; - } - </style> - <link href="player.css" type="text/css" rel="stylesheet" /> - <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> - <script src="//ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script> - <script src="js/util/Timer.js"></script> - <script src="js/util/OffsetBuffer.js"></script> - <script src="js/util/Color.js"></script> - <script src="js/util/Rectangle.js"></script> - <script src="js/Sprite.js"></script> - <script src="js/Reporter.js"></script> - <script src="js/Stage.js"></script> - <script src="js/sound/WAVFile.js"></script> - <script src="js/sound/SoundDecoder.js"></script> - <script src="js/sound/SoundBank.js"></script> - <script src="js/sound/NotePlayer.js"></script> - <script src="soundbank/Instr.js"></script> - <script src="js/IO.js"></script> - <script src="js/primitives/VarListPrims.js"></script> - <script src="js/primitives/MotionAndPenPrims.js"></script> - <script src="js/primitives/LooksPrims.js"></script> - <script src="js/primitives/SensingPrims.js"></script> - <script src="js/primitives/SoundPrims.js"></script> - <script src="js/primitives/Primitives.js"></script> - <script src="js/Interpreter.js"></script> - <script src="js/Runtime.js"></script> - <script src="js/Scratch.js"></script> - <script type="text/javascript"> - if (window.location.hash) { - var project_id = parseInt(window.location.hash.substr(1)); - } else { - var project_id = 10000160; // Default project for display - } - </script> - <script> - $(function() { - // The flashvars tell flash about the project data (and autostart=true) - var flashvars = { - server: encodeURIComponent('scratch.mit.edu'), - project_id: project_id - }; + <head> + <title>Scratch HTML5 vs. Flash</title> + <meta charset="utf-8"> + <style type="text/css"> + body { + background: #222; + color: #fff; + margin: 0; + } + </style> + <link href="player.css" type="text/css" rel="stylesheet" /> + <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> + <script src="//ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script> + <script src="js/util/Timer.js"></script> + <script src="js/util/OffsetBuffer.js"></script> + <script src="js/util/Color.js"></script> + <script src="js/util/Rectangle.js"></script> + <script src="js/Sprite.js"></script> + <script src="js/Reporter.js"></script> + <script src="js/Stage.js"></script> + <script src="js/sound/WAVFile.js"></script> + <script src="js/sound/SoundDecoder.js"></script> + <script src="js/sound/SoundBank.js"></script> + <script src="js/sound/NotePlayer.js"></script> + <script src="soundbank/Instr.js"></script> + <script src="js/IO.js"></script> + <script src="js/primitives/VarListPrims.js"></script> + <script src="js/primitives/MotionAndPenPrims.js"></script> + <script src="js/primitives/LooksPrims.js"></script> + <script src="js/primitives/SensingPrims.js"></script> + <script src="js/primitives/SoundPrims.js"></script> + <script src="js/primitives/Primitives.js"></script> + <script src="js/Interpreter.js"></script> + <script src="js/Runtime.js"></script> + <script src="js/Scratch.js"></script> + <script type="text/javascript"> + if (window.location.hash) { + var project_id = parseInt(window.location.hash.substr(1)); + } else { + var project_id = 10000160; // Default project for display + } + </script> + <script> + $(function() { + // The flashvars tell flash about the project data (and autostart=true) + var flashvars = { + server: encodeURIComponent('scratch.mit.edu'), + project_id: project_id + }; - // Pass in the cloud token for the project - if(window.getCloudToken) - flashvars.cloud_token = encodeURIComponent(getCloudToken()); + // Pass in the cloud token for the project + if (window.getCloudToken) { + flashvars.cloud_token = encodeURIComponent(getCloudToken()); + } - var params = { - allowscriptaccess: 'always', - allowfullscreen: 'false', - wmode: 'direct', - menu: 'false'}; + var params = { + allowscriptaccess: 'always', + allowfullscreen: 'false', + wmode: 'direct', + menu: 'false' + }; - var flashPlayer = null; - //var swf_url = "http://cdn.scratch.mit.edu/scratchr2/static/Scratch.swf"; - var swf_url = "http://jiggler.media.mit.edu/shanemc/scratchr2/static/Scratch.swf"; - swfobject.embedSWF(swf_url, "flashScratch", "480", "400", "10.2.0", - "http://cdn.scratch.mit.edu/scratchr2/static/expressInstall.swf", - flashvars, params, null, function(e) { - $('#flashScratch').css('visibility', 'visible'); - if(e.success) flashPlayer = e.ref; + var flashPlayer = null; + //var swf_url = "http://cdn.scratch.mit.edu/scratchr2/static/Scratch.swf"; + var swf_url = "http://jiggler.media.mit.edu/shanemc/scratchr2/static/Scratch.swf"; + swfobject.embedSWF(swf_url, "flashScratch", "480", "400", "10.2.0", + "http://cdn.scratch.mit.edu/scratchr2/static/expressInstall.swf", + flashvars, params, null, function(e) { + $('#flashScratch').css('visibility', 'visible'); + if (e.success) flashPlayer = e.ref; + }); + + $('#trigger_green_flag, #greenSlide').click(function() { + flashPlayer.ASstartRunning(); + }); + + // Stop button behavior + $('#trigger_stop').click(function() { + flashPlayer.ASstopRunning(); + }); }); - - $('#trigger_green_flag, #greenSlide').click(function() { - flashPlayer.ASstartRunning(); - }); - - // Stop button behavior - $('#trigger_stop').click(function() { - flashPlayer.ASstopRunning(); - }); - }); - </script> - </head> - <body> - <div style="display: inline-block;"> - <div id="up"> </div> - <div id="left"> </div> - <div id="overContainer"> - <div id="greenSlide"><div id="greenSlideFg"><img src="img/greenflag.png"></div></div> - <div id="container"></div> + </script> + </head> + <body> + <div style="display: inline-block;"> + <div id="up"> </div> + <div id="left"> </div> + <div id="overContainer"> + <div id="greenSlide"><div id="greenSlideFg"><img src="img/greenflag.png"></div></div> + <div id="container"></div> + </div> + <div id="right"> </div> + <div id="down"> </div> </div> - <div id="right"> </div> - <div id="down"> </div> - </div> - <div style="display: inline-block;"> - <div id="flashScratch" style="text-align:center;visibility:hidden;"> - <p style="color:#aaa;font-size:22px;margin-top:14px;line-height:28px;">Oh Noes! Scratch project cannot display.<br/>Flash player is disabled, missing, or less than version 10.2.</p> - <a href="http://www.adobe.com/go/getflashplayer"> - <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" target="_blank" /> - </a> + <div style="display: inline-block;"> + <div id="flashScratch" style="text-align:center;visibility:hidden;"> + <p style="color:#aaa;font-size:22px;margin-top:14px;line-height:28px;">Oh Noes! Scratch project cannot display.<br/>Flash player is disabled, missing, or less than version 10.2.</p> + <a href="http://www.adobe.com/go/getflashplayer"> + <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" target="_blank" /> + </a> + </div> </div> - </div> - - <div id="info">Loading...</div> + <div id="info">Loading...</div> - <button id="trigger_green_flag">Green flag</button> - <button id="trigger_stop">Stop</button> + <button id="trigger_green_flag">Green flag</button> + <button id="trigger_stop">Stop</button> - <input type="text" name="project_id" id="project_id" /><button id='go_project'>Go!</button> - </body> + <input type="text" name="project_id" id="project_id" /><button id='go_project'>Go!</button> + </body> </html> diff --git a/js/IO.js b/js/IO.js index 657317c..b9a726c 100644 --- a/js/IO.js +++ b/js/IO.js @@ -27,26 +27,24 @@ var IO = function() { // In production, simply use the local path (no proxy) // since we won't be hampered by the same-origin policy. this.base = 'proxy.php?resource=internalapi/'; - this.project_base = this.base + 'project/'; + this.project_base = this.base + 'project/'; this.project_suffix = '/get/'; this.asset_base = this.base + 'asset/'; 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) { - runningIO.data = data; - runningIO.makeObjects(); - runningIO.loadThreads(); - runningIO.loadNotesDrums(); - runtime.loadStart(); // Try to run the project. - } - ); -} + $.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,22 +79,22 @@ 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 runtime.stage = new Stage(this.data); runtime.stage.attach(runtime.scene); runtime.stage.attachPenLayer(runtime.scene); runtime.stage.loadSounds(); - + // 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,8 +105,8 @@ IO.prototype.makeObjects = function() { if (!obj.cmd) newSprite.loadSounds(); }); -} - +}; + IO.prototype.loadThreads = function() { var target = runtime.stage; var scripts = target.data.scripts; @@ -123,9 +121,9 @@ IO.prototype.loadThreads = function() { $.each(target.data.scripts, function(j, s) { target.stacks.push(interp.makeBlockList(s[2])); }); - } + } }); -} +}; // 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; -} +}; diff --git a/js/Interpreter.js b/js/Interpreter.js index d6d013d..c7bbee9 100644 --- a/js/Interpreter.js +++ b/js/Interpreter.js @@ -22,7 +22,7 @@ var Block = function(opAndArgs, optionalSubstack) { this.op = opAndArgs[0]; - this.primFcn = interp.lookupPrim(this.op); + this.primFcn = interp.lookupPrim(this.op); this.args = opAndArgs.slice(1); // arguments can be either or constants (numbers, boolean strings, etc.) or expressions (Blocks) this.isLoop = false; // set to true for loop blocks the first time they run this.substack = optionalSubstack; @@ -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,10 +54,10 @@ 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) { +Interpreter.prototype.fixArgs = function(b) { // Convert the arguments of the given block into blocks or substacks if necessary. // A block argument can be a constant (numbers, boolean strings, etc.), an expression (Blocks), or a substack (an array of blocks). var newArgs = []; @@ -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() { @@ -115,17 +115,17 @@ Interpreter.prototype.stepThreads = function() { if (this.threads[a].nextBlock != null) { newThreads.push(this.threads[a]); } - } + } this.threads = newThreads; if (this.threads.length == 0) return; } 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; @@ -141,7 +141,7 @@ Interpreter.prototype.stepActiveThread = function() { b = this.activeThread.nextBlock; // refresh local variable b in case primitive did some control flow while (b == null) { // end of a substack; pop the owning control flow block from stack - // Note: This is a loop to handle nested control flow blocks. + // Note: This is a loop to handle nested control flow blocks. b = this.activeThread.stack.pop(); if ((b == null) || (b.isLoop)) { this.activeThread.nextBlock = b; @@ -149,8 +149,8 @@ Interpreter.prototype.stepActiveThread = function() { } } } -} - +}; + Interpreter.prototype.toggleThread = function(b, targetObj) { var newThreads = [], wasRunning = false; for (var i = 0; i < this.threads.length; i++) { @@ -161,16 +161,16 @@ 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 var newThread = new Thread(b, targetObj); @@ -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,27 +247,27 @@ 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) { b.tmp = Math.max(interp.arg(b, 0), 0); // Initialize repeat count on this block @@ -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]); } @@ -303,14 +303,14 @@ Interpreter.prototype.broadcast = function(b, waitFlag) { if (interp.isRunning(interp.activeThread.tmpObj[pair][0])) { done = false; } - } + } if (done) { interp.activeThread.tmpObj = null; interp.activeThread.firstTime = true; } 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; } -} +}; diff --git a/js/Reporter.js b/js/Reporter.js index 7658201..d92011b 100644 --- a/js/Reporter.js +++ b/js/Reporter.js @@ -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) { @@ -47,7 +47,7 @@ Reporter.prototype.attach = function(scene) { // Temporarily, set the value to sliderMin until an update this.slider = $('<input type="range" min="' + this.sliderMin + '" max="' + this.sliderMax + '" step="1" value="' + - this.sliderMin + '" data-target="' + this.target + + this.sliderMin + '" data-target="' + this.target + '" data-var="' + this.param + '">'); this.slider.change(this.changeSlider); this.el.append('<br>'); @@ -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; -} +}; diff --git a/js/Runtime.js b/js/Runtime.js index de19bca..ec1126f 100644 --- a/js/Runtime.js +++ b/js/Runtime.js @@ -35,8 +35,8 @@ var Runtime = function() { this.audioPlaying = []; this.notesPlaying = []; this.projectLoaded = false; -} - +}; + // Initializer for the drawing and audio contexts. Runtime.prototype.init = function() { this.scene = $('#container'); @@ -44,8 +44,8 @@ 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 // and animate methods. @@ -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,8 +98,8 @@ 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. Runtime.prototype.allStacksDo = function(f) { @@ -106,25 +107,25 @@ 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); }); } } $.each(stage.stacks, function(index, stack) { - f(stack, stage); + f(stack, stage); }); -} - +}; + // Hat triggers Runtime.prototype.startGreenFlags = function() { function startIfGreenFlag(stack, target) { if (stack.op == 'whenGreenFlag') interp.toggleThread(stack, target); } this.allStacksDo(startIfGreenFlag); -} - +}; + Runtime.prototype.startKeyHats = function(ch) { var keyName = null; if (('A'.charCodeAt(0) <= ch) && (ch <= 'Z'.charCodeAt(0)) || @@ -140,43 +141,43 @@ 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)) - interp.toggleThread(stack, target); + 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) { if (n == 'Stage') return this.stage; var selected_sprite = null; $.each(this.sprites, function(index, s) { if (s.objName == n) { - selected_sprite = s; + selected_sprite = s; return false; } }); return selected_sprite; -} +}; Runtime.prototype.getTimeString = function(which) { // Return local time properties. @@ -191,9 +192,8 @@ 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) { var sprites = this.sprites; @@ -205,18 +205,18 @@ Runtime.prototype.reassignZ = function(target, move) { sprites.splice(index, 1); } }); - + 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 { // No change is required this.sprites.splice(oldIndex, 0, target); - } - + } + // Renumber the z-indices var newZ = 1; $.each(this.sprites, function(index, sprite) { @@ -224,4 +224,4 @@ Runtime.prototype.reassignZ = function(target, move) { sprite.updateLayer(); newZ++; }); -} +}; diff --git a/js/Scratch.js b/js/Scratch.js index f255f1c..d08ca06 100644 --- a/js/Scratch.js +++ b/js/Scratch.js @@ -23,58 +23,58 @@ 'use strict'; var runtime, interp, io, iosAudioActive = false; -$(function () { +$(function() { runtime = new Runtime(); runtime.init(); - + $(window).keydown(function(e) { runtime.keysDown[e.which] = true; runtime.startKeyHats(e.which); }); - + $(window).keyup(function(e) { delete runtime.keysDown[e.which]; }); - + // Update the project ID field $('#project_id').val(project_id); - + // Go project button behavior $('#go_project').click(function() { window.location = "#" + parseInt($('#project_id').val()); window.location.reload(true); }); - + // Green flag behavior $('#trigger_green_flag, #greenSlide').click(function() { $('#greenSlide').css('display', 'none'); runtime.greenFlag() }); - + // Stop button behavior $('#trigger_stop').click(function() { runtime.stopAll(); }); - + // Canvas container mouse events $('#container').mousedown(function(e) { runtime.mouseDown = true; //e.preventDefault(); }); - + $('#container').mouseup(function(e) { runtime.mouseDown = false; //e.preventDefault(); }); - + $('#container').mousemove(function(e) { var absX = e.pageX - this.offsetLeft; var absY = e.pageY - this.offsetTop; runtime.mousePos = [absX-240, -absY+180]; }); - + // Touch events - EXPERIMENTAL - $(window).bind('touchstart', function(e) { + $(window).bind('touchstart', function(e) { // On iOS, we need to activate the Web Audio API // with an empty sound play on the first touch event. if (!iosAudioActive) { @@ -85,8 +85,8 @@ $(function () { isource.noteOn(0); iosAudioActive = true; } - }); - + }); + $('#container').bind('touchstart', function(e) { runtime.mouseDown = true; }); @@ -94,14 +94,14 @@ $(function () { $('#container').bind('touchend', function(e) { runtime.mouseDown = true; }); - + $('#container').bind('touchmove', function(e) { var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; var absX = touch.pageX - this.offsetLeft; var absY = touch.pageY - this.offsetTop; runtime.mousePos = [absX-240, -absY+180]; }); - + // Border touch events - EXPERIMENTAL $('#left').bind('touchstart touchmove', function(e) { runtime.keysDown[37] = true; runtime.startKeyHats(37); }); $('#left').bind('touchend', function(e) { delete runtime.keysDown[37]; }); @@ -111,11 +111,11 @@ $(function () { $('#right').bind('touchend', function(e) { delete runtime.keysDown[39]; }); $('#down').bind('touchstart touchmove', function(e) { runtime.keysDown[40] = true; runtime.startKeyHats(40); }); $('#down').bind('touchend', function(e) { delete runtime.keysDown[40]; }); - + // Load the interpreter and primitives interp = new Interpreter(); interp.initPrims(); - + // Load the requested project and go! io = new IO(); io.loadProject(project_id); diff --git a/js/Sprite.js b/js/Sprite.js index ada44d9..48a1a64 100644 --- a/js/Sprite.js +++ b/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,8 +94,8 @@ 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) { // Create textures and materials for each of the costumes. @@ -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(); }) @@ -137,24 +137,23 @@ Sprite.prototype.attach = function(scene) { this.talkBubbleStyler = $('<div class="bubble-say"></div>'); this.talkBubble.append(this.talkBubbleBox); 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) { if (costume < 0) { @@ -167,34 +166,34 @@ 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!! var boxOffset = $('#container').offset(); @@ -238,34 +237,35 @@ 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]; var resolution = this.costumes[this.currentCostumeIndex].bitmapResolution || 1; - + var drawWidth = texture.width * this.scale / resolution; var drawHeight = texture.height * this.scale / resolution; - + var rotationCenterX = this.costumes[this.currentCostumeIndex].rotationCenterX; var rotationCenterY = this.costumes[this.currentCostumeIndex].rotationCenterY; - + var drawX = this.scratchX + (480 / 2) - rotationCenterX; var drawY = -this.scratchY + (360 / 2) - rotationCenterY; @@ -275,26 +275,26 @@ Sprite.prototype.updateTransform = function() { // sign to the X scale. } - $(this.mesh).css('transform', + $(this.mesh).css('transform', 'translatex(' + drawX + 'px) \ translatey(' + drawY + 'px) \ rotate(' + this.rotation + 'deg) \ scaleX(' + scaleXprepend + (this.scale / resolution) + ') scaleY(' + (this.scale / resolution) + ')'); - $(this.mesh).css('-moz-transform', + $(this.mesh).css('-moz-transform', 'translatex(' + drawX + 'px) \ translatey(' + drawY + 'px) \ rotate(' + this.rotation + 'deg) \ scaleX(' + scaleXprepend + this.scale + ') scaleY(' + this.scale / resolution + ')'); - $(this.mesh).css('-webkit-transform', + $(this.mesh).css('-webkit-transform', 'translatex(' + drawX + 'px) \ translatey(' + drawY + 'px) \ rotate(' + this.rotation + 'deg) \ scaleX(' + scaleXprepend + (this.scale / resolution) + ') scaleY(' + (this.scale / resolution) + ')'); - - $(this.mesh).css('-webkit-transform-origin', rotationCenterX + 'px ' + rotationCenterY + 'px'); - $(this.mesh).css('-moz-transform-origin', rotationCenterX + 'px ' + rotationCenterY + 'px'); - $(this.mesh).css('-ms-transform-origin', rotationCenterX + 'px ' + rotationCenterY + 'px'); - $(this.mesh).css('-o-transform-origin', rotationCenterX + 'px ' + rotationCenterY + 'px'); + + $(this.mesh).css('-webkit-transform-origin', rotationCenterX + 'px ' + rotationCenterY + 'px'); + $(this.mesh).css('-moz-transform-origin', rotationCenterX + 'px ' + rotationCenterY + 'px'); + $(this.mesh).css('-ms-transform-origin', rotationCenterX + 'px ' + rotationCenterY + 'px'); + $(this.mesh).css('-o-transform-origin', rotationCenterX + 'px ' + rotationCenterY + 'px'); $(this.mesh).css('transform-origin', rotationCenterX + 'px ' + rotationCenterY + 'px'); // Don't forget to update the talk bubble. @@ -303,9 +303,9 @@ Sprite.prototype.updateTransform = function() { this.talkBubble.css('left', xy[0] + 'px'); this.talkBubble.css('top', xy[1] + 'px'); } - - this.updateLayer(); -} + + 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 (this.visible) + if (type == 'say') { + this.talkBubbleStyler.addClass('bubble-say'); + } else if (type == 'think') { + this.talkBubbleStyler.addClass('bubble-think'); + } + + 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,23 +371,23 @@ 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() { var x = this.scratchX + 240; @@ -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,35 +410,38 @@ 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 +}; + +// Pen functions Sprite.prototype.setPenColor = function(c) { var hsv = Color.rgb2hsv(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) { +}; + +Sprite.prototype.setPenHue = function(n) { this.penHue = n % 200; if (this.penHue < 0) this.penHue += 200; this.updateCachedPenColor(); -} -Sprite.prototype.setPenShade = function(n) { +}; + +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; var drawHeight = this.textures[this.currentCostumeIndex].height * 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; -} +}; diff --git a/js/Stage.js b/js/Stage.js index 6283dab..c425e10 100644 --- a/js/Stage.js +++ b/js/Stage.js @@ -35,31 +35,28 @@ 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; this.lineCache.lineCap = 'round'; @@ -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(); -} +}; diff --git a/js/primitives/LooksPrims.js b/js/primitives/LooksPrims.js index 2556d65..174a4c7 100644 --- a/js/primitives/LooksPrims.js +++ b/js/primitives/LooksPrims.js @@ -15,7 +15,7 @@ 'use strict'; -var LooksPrims = function() {} +var LooksPrims = function() {}; LooksPrims.prototype.addPrimsTo = function(primTable) { primTable["show"] = this.primShow; @@ -42,28 +42,28 @@ LooksPrims.prototype.addPrimsTo = function(primTable) { primTable["changeGraphicEffect:by:"] = this.primChangeEffect; primTable["setGraphicEffect:to:"] = this.primSetEffect; primTable["filterReset"] = this.primClearEffects; - + primTable["say:"] = function(b) { showBubble(b, 'say'); }; 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.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(); if (s == null) return; @@ -88,8 +88,8 @@ LooksPrims.prototype.primShowCostume = function(b) { } } if (s.visible) interp.redraw(); -} - +}; + LooksPrims.prototype.primStartScene = function(b) { var s = runtime.stage; var arg = interp.arg(b, 0); @@ -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(); -} - -LooksPrims.prototype.primChangeEffect = function(b) {} + if (s.visible) interp.redraw(); +}; -LooksPrims.prototype.primSetEffect = function(b) {} +LooksPrims.prototype.primChangeEffect = function(b) {}; -LooksPrims.prototype.primClearEffects = function(b) {} +LooksPrims.prototype.primSetEffect = 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(); } -} +}; diff --git a/js/primitives/MotionAndPenPrims.js b/js/primitives/MotionAndPenPrims.js index ed57095..00345e9 100644 --- a/js/primitives/MotionAndPenPrims.js +++ b/js/primitives/MotionAndPenPrims.js @@ -15,7 +15,7 @@ 'use strict'; -var MotionAndPenPrims = function() {} +var MotionAndPenPrims = function() {}; MotionAndPenPrims.prototype.addPrimsTo = function(primTable) { primTable['forward:'] = this.primMove; @@ -26,19 +26,19 @@ MotionAndPenPrims.prototype.addPrimsTo = function(primTable) { primTable["gotoX:y:"] = this.primGoTo; primTable["gotoSpriteOrMouse:"] = this.primGoToSpriteOrMouse; primTable["glideSecs:toX:y:elapsed:from:"] = this.primGlide; - + primTable["changeXposBy:"] = this.primChangeX; primTable["xpos:"] = this.primSetX; primTable["changeYposBy:"] = this.primChangeY; primTable["ypos:"] = this.primSetY; - + primTable["bounceOffEdge"] = this.primBounceOffEdge; primTable["setRotationStyle"] = this.primSetRotationStyle; - + primTable["xpos"] = this.primXPosition; primTable["ypos"] = this.primYPosition; primTable["heading"] = this.primDirection; - + primTable["clearPenTrails"] = this.primClear; primTable["putPenDown"] = this.primPenDown; primTable["putPenUp"] = this.primPenUp; @@ -49,63 +49,62 @@ MotionAndPenPrims.prototype.addPrimsTo = function(primTable) { primTable["changePenShadeBy:"] = this.primChangePenShade; primTable["penSize:"] = this.primSetPenSize; primTable["changePenSizeBy:"] = this.primChangePenSize; - + 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,44 +118,43 @@ 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 moveSpriteTo(s, state[4], state[5]); 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)); } -} +}; diff --git a/js/primitives/Primitives.js b/js/primitives/Primitives.js index e869586..035cff7 100644 --- a/js/primitives/Primitives.js +++ b/js/primitives/Primitives.js @@ -26,57 +26,57 @@ 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); new LooksPrims().addPrimsTo(primTable); new SensingPrims().addPrimsTo(primTable); new SoundPrims().addPrimsTo(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); } - + Primitives.prototype.primModulo = function(b) { var modulus = interp.arg(b, 1); var n = interp.arg(b, 0) % modulus; @@ -90,14 +90,14 @@ 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 "log": return Math.log(n) / Math.LN10; case "e ^": return Math.exp(n); case "10 ^": return Math.exp(n * Math.LN10); } diff --git a/js/primitives/SensingPrims.js b/js/primitives/SensingPrims.js index 246def0..81e0414 100644 --- a/js/primitives/SensingPrims.js +++ b/js/primitives/SensingPrims.js @@ -15,13 +15,13 @@ 'use strict'; -var SensingPrims = function() {} +var SensingPrims = function() {}; SensingPrims.prototype.addPrimsTo = function(primTable) { primTable['touching:'] = this.primTouching; primTable['touchingColor:'] = this.primTouchingColor; primTable['color:sees:'] = this.primColorTouchingColor; - + primTable['keyPressed:'] = this.primKeyPressed; primTable['mousePressed'] = function(b) { return runtime.mouseDown; }; primTable['mouseX'] = function(b) { return runtime.mousePos[0]; }; @@ -32,27 +32,27 @@ 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(); if (s == null || !s.visible) return false; - + var arg = interp.arg(b, 0); if (arg == '_edge_') { return false; // TODO } - + if (arg == '_mouse_') { return false; // TODO } - + var s2 = runtime.spriteNamed(arg); if (s2 == null || !s2.visible) return false; - + return spriteHitTest(s, s2); -} - +}; + SensingPrims.prototype.primTouchingColor = function(b) { var s = interp.targetSprite(); if (s == null || !s.visible) return false; @@ -60,8 +60,8 @@ SensingPrims.prototype.primTouchingColor = function(b) { var color = interp.arg(b, 0); return stageColorHitTest(s, color); -} - +}; + SensingPrims.prototype.primColorTouchingColor = function(b) { var s = interp.targetSprite(); if (s == null || !s.visible) return false; @@ -70,8 +70,8 @@ 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'); hitCanvas.width = 480; @@ -91,8 +91,8 @@ var spriteHitTest = function(a, b) { } } return false; -} - +}; + var stageColorHitTest = function(target, color) { var r, g, b; r = (color >> 16); @@ -123,8 +123,8 @@ 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) { var diff_a = Math.abs(a-x); @@ -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,21 +159,21 @@ 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); var ch = key.charCodeAt(0); @@ -184,8 +184,8 @@ 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(); var p = mouseOrSpritePosition(interp.arg(b, 0)); @@ -193,8 +193,8 @@ 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); var targetSprite = runtime.spriteNamed(interp.arg(b, 1)); @@ -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(); - msSince += (now.getTimezoneOffset() - dst) * 60000; - return msSince / 86400000; -} + 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; -} +}; diff --git a/js/primitives/SoundPrims.js b/js/primitives/SoundPrims.js index 0afb178..a33f067 100644 --- a/js/primitives/SoundPrims.js +++ b/js/primitives/SoundPrims.js @@ -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) { @@ -42,11 +42,11 @@ var playSound = function(snd) { snd.source.noteOff(0); snd.source = null; } - + snd.source = runtime.audioContext.createBufferSource(); snd.source.buffer = snd.buffer; snd.source.connect(runtime.audioGain); - + // Track the sound's completion state snd.source.done = false; snd.source.finished = function() { @@ -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); @@ -81,9 +81,9 @@ var playDrum = function(drum, secs, client) { runtime.notesPlaying.splice(i, 1); } } - window.setTimeout(source.finished, secs * 1000); + window.setTimeout(source.finished, secs * 1000); return player; -} +}; var playNote = function(instrument, midiKey, secs, client) { var player = SoundBank.getNotePlayer(instrument, midiKey); @@ -99,9 +99,9 @@ var playNote = function(instrument, midiKey, secs, client) { runtime.notesPlaying.splice(i, 1); } } - window.setTimeout(source.finished, secs * 1000); + 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; +}; diff --git a/js/primitives/VarListPrims.js b/js/primitives/VarListPrims.js index 209dd30..065be7d 100644 --- a/js/primitives/VarListPrims.js +++ b/js/primitives/VarListPrims.js @@ -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,11 +91,11 @@ VarListPrims.prototype.primShowVar = function(b) { return; } } -} +}; // List primitive implementations -// Take a list name and target sprite and return the JS list itself +// Take a list name and target sprite and return the JS list itself var findList = function(targetSprite, listName) { if (targetSprite == null) targetSprite = runtime.stage; if (listName in targetSprite.lists) { @@ -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,41 +126,42 @@ 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)); if (!list) return; var newItem = interp.arg(b, 0); - + var position = interp.arg(b, 1); if (position == 'last') position = list.length; else if (position == 'random') position = Math.round(Math.random() * list.length); else position = parseInt(position) - 1; if (position > list.length) return; - + list.splice(position, 0, newItem); -} +}; VarListPrims.prototype.primListSetLine = function(b) { var list = findList(interp.targetSprite(), interp.arg(b, 1)); if (!list) return; var newItem = interp.arg(b, 2); var position = interp.arg(b, 0); - + 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; -} +}; diff --git a/js/sound/NotePlayer.js b/js/sound/NotePlayer.js index 2c0009e..8e6a410 100644 --- a/js/sound/NotePlayer.js +++ b/js/sound/NotePlayer.js @@ -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; } -} +}; diff --git a/js/sound/SoundBank.js b/js/sound/SoundBank.js index 680b03a..275a5cb 100644 --- a/js/sound/SoundBank.js +++ b/js/sound/SoundBank.js @@ -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; -} - - +}; diff --git a/js/sound/SoundDecoder.js b/js/sound/SoundDecoder.js index 781820c..fa67e88 100644 --- a/js/sound/SoundDecoder.js +++ b/js/sound/SoundDecoder.js @@ -22,7 +22,7 @@ var SoundDecoder = function(wavFileData) { this.scratchSound = null; - + this.soundData = null; this.startOffset = 0; this.endOffset = 0; @@ -37,10 +37,10 @@ var SoundDecoder = function(wavFileData) { this.thisSample = 0; // decoder state - this.sample = 0; + this.sample = 0; this.index = 0; this.lastByte = -1; // -1 indicates that there is no saved lastByte - + this.nextSample = 0; this.info = null; @@ -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) { @@ -149,13 +147,13 @@ SoundDecoder.stepTable = [ 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 ]; -SoundDecoder.prototype.getSampleADPCM = function() { +SoundDecoder.prototype.getSampleADPCM = function() { // Decompress sample data using the IMA ADPCM algorithm. - // Note: Handles only one channel, 4-bits/sample. + // 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; diff --git a/js/sound/WAVFile.js b/js/sound/WAVFile.js index a75a11a..9be1ba0 100644 --- a/js/sound/WAVFile.js +++ b/js/sound/WAVFile.js @@ -19,11 +19,10 @@ 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 = {}; - + var data = new OffsetBuffer(waveData); // read WAVE File Header @@ -31,11 +30,11 @@ WAVFile.decode = function(waveData) { var totalSize = data.readInt(); if (data.getLength() != (totalSize + 8)) console.log("WAVFile: bad RIFF size; ignoring"); if (data.readString(4) != 'WAVE') { console.log("WAVFile: not a WAVE file"); return; } - + // read format chunk var formatChunk = WAVFile.extractChunk('fmt ', data); if (formatChunk.getLength() < 16) { console.log("WAVFile: format chunk is too small"); return; } - + var encoding = formatChunk.readShort(); result.encoding = encoding; result.channels = formatChunk.readShort(); @@ -48,7 +47,7 @@ WAVFile.decode = function(waveData) { var sampleDataStartAndSize = WAVFile.dataChunkStartAndSize(data); result.sampleDataStart = sampleDataStartAndSize[0]; result.sampleDataSize = sampleDataStartAndSize[1]; - + // handle various encodings if (encoding == 1) { if (!((result.bitsPerSample == 8) || (result.bitsPerSample == 16))) { @@ -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 -} +}; diff --git a/js/util/Color.js b/js/util/Color.js index eb07d66..2e1f864 100644 --- a/js/util/Color.js +++ b/js/util/Color.js @@ -20,70 +20,70 @@ Color = function() {}; Color.fromHSV = function(h, s, v) { - var r, g, b; - h = h % 360; - if (h < 0) h += 360; - s = Math.max(0, Math.min(s, 1)); - v = Math.max(0, Math.min(v, 1)); + var r, g, b; + h = h % 360; + if (h < 0) h += 360; + s = Math.max(0, Math.min(s, 1)); + v = Math.max(0, Math.min(v, 1)); - 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))); - 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; } - else if (i == 3) { r = p; g = q; b = v; } - else if (i == 4) { r = t; g = p; b = v; } - else if (i == 5) { r = v; g = p; b = q; } - r = Math.floor(r * 255); - g = Math.floor(g * 255); - b = Math.floor(b * 255); - return (r << 16) | (g << 8) | b; -} + 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)); + 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; } + else if (i == 3) { r = p; g = q; b = v; } + else if (i == 4) { r = t; g = p; b = v; } + else if (i == 5) { r = v; g = p; b = q; } + r = Math.floor(r * 255); + 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; - var r = ((rgb >> 16) & 255) / 255; - var g = ((rgb >> 8) & 255) / 255; - var b = (rgb & 255) / 255; - 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; - s = (v - x) / v; - return [h, s, v]; -} + var h, s, v, x, f, i; + var r = ((rgb >> 16) & 255) / 255; + var g = ((rgb >> 8) & 255) / 255; + var b = (rgb & 255) / 255; + 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; + 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]); -} + 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. - if (fraction <= 0) return rgb1; - if (fraction >= 1) return rgb2; - var r1 = (rgb1 >> 16) & 255; - var g1 = (rgb1 >> 8) & 255; - var b1 = rgb1 & 255 - var r2 = (rgb2 >> 16) & 255; - var g2 = (rgb2 >> 8) & 255; - var b2 = rgb2 & 255 - var r = ((fraction * r2) + ((1.0 - fraction) * r1)) & 255; - var g = ((fraction * g2) + ((1.0 - fraction) * g1)) & 255; - var b = ((fraction * b2) + ((1.0 - fraction) * b1)) & 255; - return (r << 16) | (g << 8) | b; -} + // Mix rgb1 with rgb2. 0 gives all rgb1, 1 gives rbg2, .5 mixes them 50/50. + if (fraction <= 0) return rgb1; + if (fraction >= 1) return rgb2; + var r1 = (rgb1 >> 16) & 255; + var g1 = (rgb1 >> 8) & 255; + var b1 = rgb1 & 255 + var r2 = (rgb2 >> 16) & 255; + var g2 = (rgb2 >> 8) & 255; + var b2 = rgb2 & 255 + var r = ((fraction * r2) + ((1.0 - fraction) * r1)) & 255; + 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 - var h = 360 * Math.random(); - var s = 0.7 + (0.3 * Math.random()); - var v = 0.6 + (0.4 * Math.random()); - return Color.fromHSV(h, s, v); -} + // return a random color + var h = 360 * Math.random(); + var s = 0.7 + (0.3 * Math.random()); + var v = 0.6 + (0.4 * Math.random()); + return Color.fromHSV(h, s, v); +}; diff --git a/js/util/OffsetBuffer.js b/js/util/OffsetBuffer.js index cd69c09..cba7bed 100644 --- a/js/util/OffsetBuffer.js +++ b/js/util/OffsetBuffer.js @@ -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]; -} +}; diff --git a/js/util/Rectangle.js b/js/util/Rectangle.js index 8a556c1..3ec80bf 100644 --- a/js/util/Rectangle.js +++ b/js/util/Rectangle.js @@ -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); -} \ No newline at end of file + return !(this.left > other.right || this.right < other.left || this.top > other.bottom || this.bottom < other.top); +}; diff --git a/js/util/Timer.js b/js/util/Timer.js index 5fa4804..d6dc2a3 100644 --- a/js/util/Timer.js +++ b/js/util/Timer.js @@ -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" + + text = "Trial: " + last_trial + "ms" + "<br />\nTrials: " + this.count() + ", Avg: " + this.average() + "ms"; - if(element) { + if (element) { $(element).html(text); } else { console.log(text); } -} +};