Selaa lähdekoodia

将内置编程课组件自定义加入图标封装方法(循环、if_else)

liyanbo 3 kuukautta sitten
vanhempi
sitoutus
18189abf2b

+ 155 - 1
src/api/blockly/blockly.js

@@ -14,6 +14,9 @@ import pauseImage from '@/assets/images/blockly/component/pause.png';
 import play_soundImage from '@/assets/images/blockly/component/sound.png';
 import constructImage from '@/assets/images/blockly/component/construct.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 lightYellowImage from '@/assets/images/blockly/light/yellow.png';
 import lightGreenImage from '@/assets/images/blockly/light/green.png';
@@ -286,6 +289,77 @@ const availableBlocks = {
     },
     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类型)
   when_passed: {
     jsonConfig: {
@@ -466,6 +540,47 @@ const availableGenerators = {
     const shape = block.getFieldValue('SHAPE');
     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) {
     const seconds = block.getFieldValue('SECONDS');
@@ -524,6 +639,45 @@ const availablePythonGenerators = {
     const shape = block.getFieldValue('SHAPE');
     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) {
     const seconds = block.getFieldValue('SECONDS');
@@ -626,7 +780,7 @@ export function setupBlocklyChineseLocale() {
     LOGIC_BOOLEAN_TOOLTIP: "返回一个布尔值:真或假。",
 
     // 循环积木中文配置
-    CONTROLS_REPEAT_TITLE: "重复%1次",
+    CONTROLS_REPEAT_TITLE: "重复执行%1次",
     CONTROLS_REPEAT_TOOLTIP: "重复执行内部代码指定次数。",
     CONTROLS_REPEAT_MSG_DO: "执行",
     CONTROLS_REPEAT_INPUT_DO: "执行",

BIN
src/assets/images/blockly/component/if.png


BIN
src/assets/images/blockly/component/if_else.png


BIN
src/assets/images/blockly/component/repeat.png