forked from marva/sumorobot-web
Create blockly.js
This commit is contained in:
parent
db079ee6b7
commit
acb9effd52
250
assets/js/blockly.js
Normal file
250
assets/js/blockly.js
Normal file
@ -0,0 +1,250 @@
|
||||
window.addEventListener("load", function() {
|
||||
// To remember the control_if blockId
|
||||
var controlBlockId = "";
|
||||
|
||||
// Change the if block to be more cheerful
|
||||
Blockly.Msg.LOGIC_HUE = '#44CC00';
|
||||
|
||||
// Remote previous and next statement from control_if block
|
||||
Blockly.defineBlocksWithJsonArray([
|
||||
{
|
||||
"type": "controls_if",
|
||||
"message0": "%{BKY_CONTROLS_IF_MSG_IF} %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "IF0",
|
||||
"check": "Boolean"
|
||||
}
|
||||
],
|
||||
"message1": "%{BKY_CONTROLS_IF_MSG_THEN} %1",
|
||||
"args1": [
|
||||
{
|
||||
"type": "input_statement",
|
||||
"name": "DO0"
|
||||
}
|
||||
],
|
||||
"colour": "%{BKY_LOGIC_HUE}",
|
||||
"helpUrl": "%{BKY_CONTROLS_IF_HELPURL}",
|
||||
"mutator": "controls_if_mutator",
|
||||
"extensions": ["controls_if_tooltip"]
|
||||
}
|
||||
]);
|
||||
|
||||
// Make control_if mutator icon bigger
|
||||
Blockly.Icon.prototype.renderIcon = function(cursorX) {
|
||||
if (this.collapseHidden && this.block_.isCollapsed()) {
|
||||
this.iconGroup_.setAttribute('display', 'none');
|
||||
return cursorX;
|
||||
}
|
||||
this.iconGroup_.setAttribute('display', 'block');
|
||||
|
||||
var SIZE = 1.7;
|
||||
var TOP_MARGIN = 2;
|
||||
var LEFT_MARGIN = 5;
|
||||
var width = this.SIZE;
|
||||
if (this.block_.RTL) {
|
||||
cursorX -= width;
|
||||
}
|
||||
this.iconGroup_.setAttribute('transform',
|
||||
'translate(' + LEFT_MARGIN + ',' + TOP_MARGIN + ') scale(' + SIZE + ')');
|
||||
this.computeIconLocation();
|
||||
if (this.block_.RTL) {
|
||||
cursorX -= Blockly.BlockSvg.SEP_SPACE_X;
|
||||
} else {
|
||||
cursorX += width + Blockly.BlockSvg.SEP_SPACE_X;
|
||||
}
|
||||
return cursorX;
|
||||
};
|
||||
|
||||
// When mouse click occures on Blockly workspace
|
||||
Blockly.utils.isRightButton = function(e) {
|
||||
var target = e.target;
|
||||
|
||||
// When control_if block is in use
|
||||
if (controlBlockId != "") {
|
||||
// When the user clicks anywhere outside the mutator and not on the mutator icon
|
||||
if (!$(target).is('.blocklyBubbleCanvas') && !$(target).parents().is('.blocklyBubbleCanvas')) {
|
||||
if (!$(target).is('.blocklyIconGroup') && !$(target).parents().is('.blocklyIconGroup')) {
|
||||
// Hide the mutator
|
||||
workspace.getBlockById(controlBlockId).mutator.setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Disable right click on Blockly workspace
|
||||
return false;
|
||||
};
|
||||
|
||||
Blockly.Blocks['sumorobot_sleep'] = {
|
||||
init: function() {
|
||||
this.setColour("#E64C00");
|
||||
this.appendDummyInput()
|
||||
.appendField("sleep")
|
||||
.appendField(new Blockly.FieldTextInput('1000',
|
||||
Blockly.FieldNumber.numberValidator), 'SLEEP');
|
||||
this.setPreviousStatement(true);
|
||||
this.setNextStatement(true);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['sumorobot_move'] = {
|
||||
init: function() {
|
||||
var OPERATORS = [
|
||||
['move stop', 'STOP'],
|
||||
['move left', 'LEFT'],
|
||||
['move right', 'RIGHT'],
|
||||
['move search', 'SEARCH'],
|
||||
['move forward', 'FORWARD'],
|
||||
['move backward', 'BACKWARD']
|
||||
];
|
||||
this.setColour("#E60000");
|
||||
var dropdown = new Blockly.FieldDropdown(OPERATORS);
|
||||
this.appendDummyInput().appendField(dropdown, 'MOVE');
|
||||
this.setPreviousStatement(true);
|
||||
this.setNextStatement(true);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['sumorobot_opponent'] = {
|
||||
init: function() {
|
||||
this.setColour("#0099E6");
|
||||
this.appendDummyInput().appendField('opponent');
|
||||
this.setOutput(true, 'Boolean');
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['sumorobot_line'] = {
|
||||
init: function() {
|
||||
var OPERATORS = [
|
||||
['line left', 'LEFT'],
|
||||
['line right', 'RIGHT']
|
||||
];
|
||||
this.setColour("#E6BF00");
|
||||
var dropdown = new Blockly.FieldDropdown(OPERATORS);
|
||||
this.appendDummyInput().appendField(dropdown, 'LINE');
|
||||
this.setOutput(true, 'Boolean');
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Python['sumorobot_sleep'] = function(block) {
|
||||
var code = 'sumorobot.sleep(' + parseFloat(block.getFieldValue('SLEEP')) + ', "' + block.id + '")\n';
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.Python['sumorobot_move'] = function(block) {
|
||||
var code = 'sumorobot.move(' + block.getFieldValue('MOVE') + ', "' + block.id + '")\n';
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.Python['sumorobot_opponent'] = function(block) {
|
||||
var code = 'sumorobot.is_opponent("' + block.id + '")';
|
||||
return [code, Blockly.Python.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
Blockly.Python['sumorobot_line'] = function(block) {
|
||||
var code = 'sumorobot.is_line(' + block.getFieldValue('LINE') + ', "' + block.id + '")';
|
||||
return [code, Blockly.Python.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
// Inject Blockly
|
||||
var blocklyArea = document.getElementById('blocklyArea');
|
||||
var blocklyDiv = document.getElementById('blocklyDiv');
|
||||
var workspace = Blockly.inject(blocklyDiv, {
|
||||
scrollbars: false,
|
||||
media: 'assets/blockly/media/',
|
||||
trashcan: true,
|
||||
sounds: true,
|
||||
zoom: {
|
||||
controls: true,
|
||||
startScale: 1.2
|
||||
},
|
||||
toolbox: document.getElementById('toolbox')
|
||||
});
|
||||
|
||||
// On Blockly resize
|
||||
var onresize = function(e) {
|
||||
// Compute the absolute coordinates and dimensions of blocklyArea.
|
||||
var element = blocklyArea;
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
do {
|
||||
x += element.offsetLeft;
|
||||
y += element.offsetTop;
|
||||
element = element.offsetParent;
|
||||
} while (element);
|
||||
// Position blocklyDiv over blocklyArea
|
||||
blocklyDiv.style.left = x + 'px';
|
||||
blocklyDiv.style.top = y + 'px';
|
||||
blocklyDiv.style.width = blocklyArea.offsetWidth + 'px';
|
||||
blocklyDiv.style.height = blocklyArea.offsetHeight + 'px';
|
||||
};
|
||||
window.addEventListener('resize', onresize, false);
|
||||
onresize();
|
||||
Blockly.svgResize(workspace);
|
||||
|
||||
// Retrieve the blocks
|
||||
var xml = Blockly.Xml.textToDom(getLocalStorageItem("sumorobot.blockly"));
|
||||
// Resume the blocks
|
||||
Blockly.Xml.domToWorkspace(xml, workspace);
|
||||
|
||||
// On Blockly code change
|
||||
function onCodeChanged(event) {
|
||||
// When the if condition block was created
|
||||
if (event.type == Blockly.Events.CREATE && event.xml.getAttributeNode("type").nodeValue == "controls_if") {
|
||||
// Remember the control_if block id
|
||||
controlBlockId = event.blockId;
|
||||
// Get the control_if block object
|
||||
var block = workspace.getBlockById(event.blockId);
|
||||
// When the control_if block doesn't already have an else
|
||||
if (block.elseCount_ == 0) {
|
||||
// Automatically add the else statement input
|
||||
block.elseCount_ = 1;
|
||||
block.updateShape_();
|
||||
}
|
||||
// When the if condition block was removed
|
||||
} else if (event.type == Blockly.Events.DELETE && event.oldXml.getAttributeNode("type").nodeValue == "controls_if") {
|
||||
// Remove the control_if block id
|
||||
controlBlockId = "";
|
||||
// Enable the if condition block
|
||||
workspace.updateToolbox(document.getElementById("toolbox"));
|
||||
}
|
||||
|
||||
// Only process change and move commands
|
||||
if (event.type != Blockly.Events.CHANGE && event.type != Blockly.Events.MOVE) return;
|
||||
// Generate code from the used blocks
|
||||
sumorobot.setBlocklyCode(Blockly.Python.workspaceToCode(workspace));
|
||||
|
||||
// Show the code in the ace editor, filter out block IDs
|
||||
readOnlyCodingEditor.setValue("\n" + sumorobot.getBlocklyCode().replace(/[,]?[ ]?"(.*?)"/g, ""));
|
||||
readOnlyCodingEditor.clearSelection();
|
||||
|
||||
// Save the code to the local storage
|
||||
var xml = Blockly.Xml.workspaceToDom(workspace);
|
||||
localStorage.setItem("sumorobot.blockly", Blockly.Xml.domToText(xml));
|
||||
|
||||
// When control_if block is used
|
||||
if (controlBlockId != "") {
|
||||
// Disable the if condition block
|
||||
workspace.updateToolbox(document.getElementById("toolbox_no_if"));
|
||||
}
|
||||
}
|
||||
|
||||
// Add a change listener to Blockly
|
||||
workspace.addChangeListener(onCodeChanged);
|
||||
|
||||
// Set a click listener on the document
|
||||
$(document).click(function(e) {
|
||||
var target = e.target;
|
||||
|
||||
// When control_if block is in use
|
||||
if (controlBlockId != "") {
|
||||
// When the user clicks anywhere outside the mutator and not on the mutator icon
|
||||
if (!$(target).is('.blocklyBubbleCanvas') && !$(target).parents().is('.blocklyBubbleCanvas')) {
|
||||
if (!$(target).is('.blocklyIconGroup') && !$(target).parents().is('.blocklyIconGroup')) {
|
||||
// Hide the mutator
|
||||
workspace.getBlockById(controlBlockId).mutator.setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user