Programming Introduction
Some block attributes contain JavaScript code:
NumericBlock label Distance updateCode var xDiff = %x1 - %x2; var yDiff = %y1 - %y2; this.setValue( Math.sqrt( xDiff * xDiff + yDiff * yDiff ) ); end
In the above code, the block uses this to refer to it's own methods.
The code can also refer to a blocks object, which is a collection of all the blocks in the section. An expression of the form %blockName is a shortcut for blocks.blockName.value. For example:
SomeBlock updateCode if (%fuel <= 0) { %xAcceleration = 0; %yAcceleration = 0; } end
You can use the section object for data you want to share between blocks within a single section:
GoalBlock label Avoid crashing goalCode return section.crashed == false; DrawBlock canvasWidth 100 canvasHeight 100 updateCode if (%x > 10 && %y < 10) { section.crashed = true; } end drawCode ctx.drawCircle( %x, %y, 20 ); end
You can use the lesson object for data you want to share between sections within a single lesson. The following code shows a variety of different variable types:
var xDiff = %x1 - %x2; this.xDiff = xDiff + $offset * @dt; %xDiffScaled = xDiff * section.scale; section.computed = true; lesson.xDiff = xDiff;
Here xDiff is an ordinary local variable; %x1 refers to blocks.x1.value; $offset is a constant defined by a macro; @dt is a built-in macro; this.xDiff is a custom variable attached to the current block; section.scale and section.computed are section-wide variables that can be be used by any block; lesson.xDiff is a variable that is shared between sections within the lesson.
You can use any built-in JavaScript functions described on the libraries documentation page. Some functions are defined in custom libraries, which you can import using an importLib command:
importLib drawItem
Most browsers have a JavaScript debugging console. In Chrome and FireFox you can access
the console using Ctrl-Shift-J (on a PC). This brings up two panels on the bottom of the page.
One lets you look at the code and the other shows you any error and diagnostic messages.
(You can use console.log( x ) to display a diagnostic message.)
In debug mode, the lesson code has two sides. The left is compressed. The corresponding uncompressed code is on the right. So if the browser complains that a7 is undefined, find the line with a7 and look at the right side to see what uncompressed name is causing the trouble.
A note on inheritance:
If block B inherits from block A, this means that block B includes the attributes and methods of block A (in addition to its own attributes and methods). If block A has an attribute x, block B will also have an attribute x. You do not need to create a block A in order to inherit from it, just create the block B and specify attributes normally.
For example, the InputBlock inherits from NumericBlock and BaseBlock. This means that an InputBlock has an initValue attribute (from the NumericBlock) and a label attribute (from the BaseBlock).
A note on event order:
Every block can have the following event code attributes defined:
- initCode: specifies code run when the section is loaded
- updateCode: specifies code to run on simulate/game updates (if the ControlBlock is defined and running)
Certain block types have other kinds of events (via changeCode, mouseTouchCode, drawCode, etc.). See the block documentation for more information.
Each lesson section has three different periodic timer events:
- the user interface timer (checks goals, handles input validation display)
- the update timer (computes the value of each block, and runs updateCode)
- the draw timer (runs drawCode)
The first timer always runs. The update timer and draw timer run only if a ControlBlock is defined and running. The ControlBlock's updatesPerSecond determines the frequency of the update timer. The ControlBlock's drawPerSecond determines the frequency of the draw timer.
In more detail, the following happens on each update timer:
- compute the value of every block that has a value expression (in template order)
- run updateCode for every block with updateCode (in template order)
- update history for every numeric block (in template order)
The following happens on each draw timer:
- run drawCode for every block with drawCode (in template order)
- update block pop-up plots (in template order)
Note: template order means specifically the order within the template, not the order on the section produced from the template (grouping blocks allow the section block order to be different from the template block order).