|
@@ -14,6 +14,9 @@ import pauseImage from '@/assets/images/blockly/component/pause.png';
|
|
|
import play_soundImage from '@/assets/images/blockly/component/sound.png';
|
|
import play_soundImage from '@/assets/images/blockly/component/sound.png';
|
|
|
import constructImage from '@/assets/images/blockly/component/construct.png';
|
|
import constructImage from '@/assets/images/blockly/component/construct.png';
|
|
|
import lightImage from '@/assets/images/blockly/component/light.png';
|
|
import lightImage from '@/assets/images/blockly/component/light.png';
|
|
|
|
|
+import repeatImage from '@/assets/images/blockly/component/repeat.png';
|
|
|
|
|
+import ifImage from '@/assets/images/blockly/component/if.png';
|
|
|
|
|
+import ifElseImage from '@/assets/images/blockly/component/if_else.png';
|
|
|
import lightRedImage from '@/assets/images/blockly/light/red.png';
|
|
import lightRedImage from '@/assets/images/blockly/light/red.png';
|
|
|
import lightYellowImage from '@/assets/images/blockly/light/yellow.png';
|
|
import lightYellowImage from '@/assets/images/blockly/light/yellow.png';
|
|
|
import lightGreenImage from '@/assets/images/blockly/light/green.png';
|
|
import lightGreenImage from '@/assets/images/blockly/light/green.png';
|
|
@@ -286,6 +289,77 @@ const availableBlocks = {
|
|
|
},
|
|
},
|
|
|
isGeneral: true
|
|
isGeneral: true
|
|
|
},
|
|
},
|
|
|
|
|
+ // 逻辑积木 - 自定义如果否则带图标
|
|
|
|
|
+ controls_if: {
|
|
|
|
|
+ jsonConfig: {
|
|
|
|
|
+ "type": "controls_if",
|
|
|
|
|
+ "message0": "%1 如果 %2",
|
|
|
|
|
+ "args0": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "type": "field_image",
|
|
|
|
|
+ "src": ifImage,
|
|
|
|
|
+ "width": 20,
|
|
|
|
|
+ "height": 20,
|
|
|
|
|
+ "alt": "条件"
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "type": "input_value",
|
|
|
|
|
+ "name": "IF0",
|
|
|
|
|
+ "check": "Boolean"
|
|
|
|
|
+ }
|
|
|
|
|
+ ],
|
|
|
|
|
+ "message1": "执行%1",
|
|
|
|
|
+ "args1": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "type": "input_statement",
|
|
|
|
|
+ "name": "DO0"
|
|
|
|
|
+ }
|
|
|
|
|
+ ],
|
|
|
|
|
+ "previousStatement": null,
|
|
|
|
|
+ "nextStatement": null,
|
|
|
|
|
+ "colour": 210,
|
|
|
|
|
+ "tooltip": "如果条件为真,则执行相应的代码。",
|
|
|
|
|
+ "helpUrl": "",
|
|
|
|
|
+ "mutator": "controls_if_mutator"
|
|
|
|
|
+ },
|
|
|
|
|
+ isGeneral: true // 标记为通用积木
|
|
|
|
|
+ },
|
|
|
|
|
+ // 循环积木 - 自定义重复执行带图标
|
|
|
|
|
+ controls_repeat_ext: {
|
|
|
|
|
+ jsonConfig: {
|
|
|
|
|
+ "type": "controls_repeat_ext",
|
|
|
|
|
+ "message0": "%1 重复 %2 次",
|
|
|
|
|
+ "args0": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "type": "field_image",
|
|
|
|
|
+ "src": repeatImage,
|
|
|
|
|
+ "width": 25,
|
|
|
|
|
+ "height": 25,
|
|
|
|
|
+ "alt": "循环"
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "type": "field_number",
|
|
|
|
|
+ "name": "TIMES",
|
|
|
|
|
+ "value": 1,
|
|
|
|
|
+ "min": 1,
|
|
|
|
|
+ "max": 100
|
|
|
|
|
+ }
|
|
|
|
|
+ ],
|
|
|
|
|
+ "message1": "执行 %1",
|
|
|
|
|
+ "args1": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "type": "input_statement",
|
|
|
|
|
+ "name": "DO"
|
|
|
|
|
+ }
|
|
|
|
|
+ ],
|
|
|
|
|
+ "previousStatement": null,
|
|
|
|
|
+ "nextStatement": null,
|
|
|
|
|
+ "colour": "#5BA55B",
|
|
|
|
|
+ "tooltip": "重复执行内部代码指定次数",
|
|
|
|
|
+ "helpUrl": ""
|
|
|
|
|
+ },
|
|
|
|
|
+ isGeneral: true // 标记为通用积木
|
|
|
|
|
+ },
|
|
|
// 当经过某个形状的积木(可作为参数使用的value类型)
|
|
// 当经过某个形状的积木(可作为参数使用的value类型)
|
|
|
when_passed: {
|
|
when_passed: {
|
|
|
jsonConfig: {
|
|
jsonConfig: {
|
|
@@ -466,6 +540,47 @@ const availableGenerators = {
|
|
|
const shape = block.getFieldValue('SHAPE');
|
|
const shape = block.getFieldValue('SHAPE');
|
|
|
return [`whenPassed('${shape}')`, javascriptGenerator.ORDER_FUNCTION_CALL];
|
|
return [`whenPassed('${shape}')`, javascriptGenerator.ORDER_FUNCTION_CALL];
|
|
|
},
|
|
},
|
|
|
|
|
+ // 条件判断生成器 - 使用Blockly默认实现方式确保兼容性
|
|
|
|
|
+ controls_if: function(block) {
|
|
|
|
|
+ let code = '';
|
|
|
|
|
+ let branchCode, conditionCode;
|
|
|
|
|
+ let n = 0;
|
|
|
|
|
+
|
|
|
|
|
+ // 生成if条件
|
|
|
|
|
+ if (block.getInput('IF0')) {
|
|
|
|
|
+ conditionCode = javascriptGenerator.valueToCode(block, 'IF0', javascriptGenerator.ORDER_NONE) || 'false';
|
|
|
|
|
+ branchCode = javascriptGenerator.statementToCode(block, 'DO0');
|
|
|
|
|
+ code += `if (${conditionCode}) {
|
|
|
|
|
+${javascriptGenerator.prefixLines(branchCode, javascriptGenerator.INDENT)}}
|
|
|
|
|
+`;
|
|
|
|
|
+ n = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 生成else if条件
|
|
|
|
|
+ for (; block.getInput('IF' + n); n++) {
|
|
|
|
|
+ conditionCode = javascriptGenerator.valueToCode(block, 'IF' + n, javascriptGenerator.ORDER_NONE) || 'false';
|
|
|
|
|
+ branchCode = javascriptGenerator.statementToCode(block, 'DO' + n);
|
|
|
|
|
+ code += `else if (${conditionCode}) {
|
|
|
|
|
+${javascriptGenerator.prefixLines(branchCode, javascriptGenerator.INDENT)}}
|
|
|
|
|
+`;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 生成else条件
|
|
|
|
|
+ if (block.getInput('ELSE')) {
|
|
|
|
|
+ const elseCode = javascriptGenerator.statementToCode(block, 'ELSE');
|
|
|
|
|
+ code += `else {
|
|
|
|
|
+${javascriptGenerator.prefixLines(elseCode, javascriptGenerator.INDENT)}}
|
|
|
|
|
+`;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return code;
|
|
|
|
|
+ },
|
|
|
|
|
+ controls_repeat_ext: function(block) {
|
|
|
|
|
+ const repeats = block.getFieldValue('TIMES');
|
|
|
|
|
+ const branch = javascriptGenerator.statementToCode(block, 'DO');
|
|
|
|
|
+ const code = `for (let i = 0; i < ${repeats}; i++) {\n${javascriptGenerator.prefixLines(branch, javascriptGenerator.INDENT)}}\n`;
|
|
|
|
|
+ return code;
|
|
|
|
|
+ },
|
|
|
// 特殊生成器 - 可根据配置动态加载
|
|
// 特殊生成器 - 可根据配置动态加载
|
|
|
pause: function(block) {
|
|
pause: function(block) {
|
|
|
const seconds = block.getFieldValue('SECONDS');
|
|
const seconds = block.getFieldValue('SECONDS');
|
|
@@ -524,6 +639,45 @@ const availablePythonGenerators = {
|
|
|
const shape = block.getFieldValue('SHAPE');
|
|
const shape = block.getFieldValue('SHAPE');
|
|
|
return [`when_passed('${shape}')`, pythonGenerator.ORDER_FUNCTION_CALL];
|
|
return [`when_passed('${shape}')`, pythonGenerator.ORDER_FUNCTION_CALL];
|
|
|
},
|
|
},
|
|
|
|
|
+ // 条件判断生成器
|
|
|
|
|
+ controls_if: function(block) {
|
|
|
|
|
+ const n = block.elseifCount_;
|
|
|
|
|
+ let code = '';
|
|
|
|
|
+ let branchCode = '';
|
|
|
|
|
+ let branchCondition = '';
|
|
|
|
|
+
|
|
|
|
|
+ // 生成if条件
|
|
|
|
|
+ branchCondition = pythonGenerator.valueToCode(block, 'IF0', pythonGenerator.ORDER_NONE) || 'False';
|
|
|
|
|
+ branchCode = pythonGenerator.statementToCode(block, 'DO0');
|
|
|
|
|
+ code += `if ${branchCondition}:
|
|
|
|
|
+${pythonGenerator.prefixLines(branchCode, pythonGenerator.INDENT)}
|
|
|
|
|
+`;
|
|
|
|
|
+
|
|
|
|
|
+ // 生成else if条件
|
|
|
|
|
+ for (let i = 1; i <= n; i++) {
|
|
|
|
|
+ branchCondition = pythonGenerator.valueToCode(block, 'IF' + i, pythonGenerator.ORDER_NONE) || 'False';
|
|
|
|
|
+ branchCode = pythonGenerator.statementToCode(block, 'DO' + i);
|
|
|
|
|
+ code += `elif ${branchCondition}:
|
|
|
|
|
+${pythonGenerator.prefixLines(branchCode, pythonGenerator.INDENT)}
|
|
|
|
|
+`;
|
|
|
|
|
+ }
|
|
|
|
|
+debugger
|
|
|
|
|
+ // 生成else条件
|
|
|
|
|
+ const elseCode = pythonGenerator.statementToCode(block, 'ELSE');
|
|
|
|
|
+ if (elseCode) {
|
|
|
|
|
+ code += `else:
|
|
|
|
|
+${pythonGenerator.prefixLines(elseCode, pythonGenerator.INDENT)}
|
|
|
|
|
+`;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return code;
|
|
|
|
|
+ },
|
|
|
|
|
+ controls_repeat_ext: function(block) {
|
|
|
|
|
+ const repeats = block.getFieldValue('TIMES');
|
|
|
|
|
+ const branch = pythonGenerator.statementToCode(block, 'DO');
|
|
|
|
|
+ const code = `for i in range(${repeats}):\n${pythonGenerator.prefixLines(branch, pythonGenerator.INDENT)}\n`;
|
|
|
|
|
+ return code;
|
|
|
|
|
+ },
|
|
|
// 特殊生成器 - 可根据配置动态加载
|
|
// 特殊生成器 - 可根据配置动态加载
|
|
|
pause: function(block) {
|
|
pause: function(block) {
|
|
|
const seconds = block.getFieldValue('SECONDS');
|
|
const seconds = block.getFieldValue('SECONDS');
|
|
@@ -626,7 +780,7 @@ export function setupBlocklyChineseLocale() {
|
|
|
LOGIC_BOOLEAN_TOOLTIP: "返回一个布尔值:真或假。",
|
|
LOGIC_BOOLEAN_TOOLTIP: "返回一个布尔值:真或假。",
|
|
|
|
|
|
|
|
// 循环积木中文配置
|
|
// 循环积木中文配置
|
|
|
- CONTROLS_REPEAT_TITLE: "重复%1次",
|
|
|
|
|
|
|
+ CONTROLS_REPEAT_TITLE: "重复执行%1次",
|
|
|
CONTROLS_REPEAT_TOOLTIP: "重复执行内部代码指定次数。",
|
|
CONTROLS_REPEAT_TOOLTIP: "重复执行内部代码指定次数。",
|
|
|
CONTROLS_REPEAT_MSG_DO: "执行",
|
|
CONTROLS_REPEAT_MSG_DO: "执行",
|
|
|
CONTROLS_REPEAT_INPUT_DO: "执行",
|
|
CONTROLS_REPEAT_INPUT_DO: "执行",
|