Adding Hat Blocks
Hat Block Activation
There are two ways a hat block can be activated. They can be activated by telling the Scratch interpreter to execute it elsewhere in the code or by the Scratch interpreter constantly polling to see if the condition is true (this is called edge triggered).
Adding the block
Just like all other blocks, hat blocks need to be defined in Specs.as
. We are going to add two hat blocks:
Add the new hat blocks to the // triggers
(the Events category) section:
// triggers
["when %b", "h", 5, "whenBool", ""],
["when project is about to be saved", "h", 5, "whenAboutToSave", ""],
In Interpreter.as
, add both blocks to the primTable
with the function primNoop
.
primTable["whenBool"] = primNoop;
primTable["whenAboutToSave"] = primNoop;
Edge Triggered Hat Blocks
Edge triggered hat blocks are implemented in a function called startEdgeTriggeredHats
, which is located in src/scratch/ScratchRuntime.as
. Add your block as a new else if
block just before the else if (app.jsEnabled)
line.
protected function startEdgeTriggeredHats(hat:Block, target:ScratchObj):void {
if (!hat.isHat || !hat.nextBlock) return; // skip disconnected hats
if ('whenSensorGreaterThan' == hat.op) {
// ...
} else if ('whenSensorConnected' == hat.op) {
// ...
} else if ('whenBool' == hat.op) {
if(interp.boolarg(hat, 0)) {
if (triggeredHats.indexOf(hat) == -1) {
if (!interp.isRunning(hat, target)) interp.toggleThread(hat, target);
}
activeHats.push(hat);
}
} else if (app.jsEnabled) {
// ...
}
}
Non-Edge Triggered Hat Blocks
Unlike edge triggered blocks, the Scratch interpreter is not constantly checking if a condition is true, instead it is up to you to tell it when you want it to run.
First, in src/scratch/ScratchRuntime.as
, add a function in the section called Hat Blocks
:
// -----------------------------
// Hat Blocks
//------------------------------
public function startAboutToSave():void {
for each (var stack:Block in clickedObj.scripts) {
if(stack.op == 'whenAboutToSave') {
interp.restartThread(stack, clickedObj);
}
}
}
To actually activate the block you need to call this function somewhere. In this case, we want to call the block from the function that saves the project. That function is exportProjectToFile
in Scratch.as
public function exportProjectToFile(fromJS:Boolean = false, saveCallback:Function = null):void {
function squeakSoundsConverted():void {
// ...
}
function fileSaved(e:Event):void {
// ...
}
if (loadInProgress) return;
runtime.startAboutToSave();
var projIO:ProjectIO = new ProjectIO(this);
projIO.convertSqueakSounds(stagePane, squeakSoundsConverted);
}
Completed Files
These files contain source code from the Your First Scratch Mod tutorial series.
File | Download |
---|---|
src/Specs.as | Specs.as |
src/scratch/ScratchRuntime.as | ScratchRuntime.as |
src/scratch/Scratch.as | Scratch.as |
src/interpreter/Interpreter.as | Interpreter.as |