|
|
@@ -2,6 +2,8 @@ import * as Blockly from "blockly";
|
|
|
import 'blockly/msg/zh-hans';
|
|
|
import { javascriptGenerator } from "blockly/javascript";
|
|
|
import { pythonGenerator } from "blockly/python";
|
|
|
+// 导入图片资源
|
|
|
+import xianqianImage from '@/assets/images/blockly/component/xianqian.png';
|
|
|
|
|
|
/**
|
|
|
* 定义所有可用的自定义积木配置
|
|
|
@@ -11,26 +13,36 @@ const availableBlocks = {
|
|
|
move_forward: {
|
|
|
jsonConfig: {
|
|
|
"type": "move_forward",
|
|
|
- "message0": "向前移动",
|
|
|
+ "message0": "%1 向前移动",
|
|
|
+ "args0": [
|
|
|
+ {
|
|
|
+ "type": "field_image",
|
|
|
+ "src": xianqianImage,
|
|
|
+ "width": 16,
|
|
|
+ "height": 16,
|
|
|
+ "alt": "向前移动"
|
|
|
+ }
|
|
|
+ ],
|
|
|
"previousStatement": null,
|
|
|
"nextStatement": null,
|
|
|
"colour": 230,
|
|
|
"tooltip": "控制角色向前移动一格",
|
|
|
- "helpUrl": "",
|
|
|
- "icon": {
|
|
|
- "src": "▶",
|
|
|
- "width": 16,
|
|
|
- "height": 16,
|
|
|
- "alt": "向前移动"
|
|
|
- }
|
|
|
+ "helpUrl": ""
|
|
|
},
|
|
|
isGeneral: true // 标记为通用积木
|
|
|
},
|
|
|
move_forward_param: {
|
|
|
jsonConfig: {
|
|
|
"type": "move_forward_param",
|
|
|
- "message0": "向前移动 %1 次",
|
|
|
+ "message0": "%1 向前移动 %2 次",
|
|
|
"args0": [
|
|
|
+ {
|
|
|
+ "type": "field_image",
|
|
|
+ "src": xianqianImage,
|
|
|
+ "width": 16,
|
|
|
+ "height": 16,
|
|
|
+ "alt": "向前移动多次"
|
|
|
+ },
|
|
|
{
|
|
|
"type": "field_number",
|
|
|
"name": "PARAM",
|
|
|
@@ -44,39 +56,43 @@ const availableBlocks = {
|
|
|
"nextStatement": null,
|
|
|
"colour": 230,
|
|
|
"tooltip": "控制角色向前移动指定次数",
|
|
|
- "helpUrl": "",
|
|
|
- "icon": {
|
|
|
- "src": "▶",
|
|
|
- "width": 16,
|
|
|
- "height": 16,
|
|
|
- "alt": "向前移动多次"
|
|
|
- }
|
|
|
+ "helpUrl": ""
|
|
|
},
|
|
|
isGeneral: true // 标记为通用积木
|
|
|
},
|
|
|
move_backward: {
|
|
|
jsonConfig: {
|
|
|
"type": "move_backward",
|
|
|
- "message0": "向后移动",
|
|
|
+ "message0": "%1 向后移动",
|
|
|
+ "args0": [
|
|
|
+ {
|
|
|
+ "type": "field_image",
|
|
|
+ "src": xianqianImage,
|
|
|
+ "width": 16,
|
|
|
+ "height": 16,
|
|
|
+ "alt": "向后移动"
|
|
|
+ }
|
|
|
+ ],
|
|
|
"previousStatement": null,
|
|
|
"nextStatement": null,
|
|
|
"colour": 230,
|
|
|
"tooltip": "控制角色向后移动一格",
|
|
|
- "helpUrl": "",
|
|
|
- "icon": {
|
|
|
- "src": "▶",
|
|
|
- "width": 16,
|
|
|
- "height": 16,
|
|
|
- "alt": "向后移动"
|
|
|
- }
|
|
|
+ "helpUrl": ""
|
|
|
},
|
|
|
isGeneral: true
|
|
|
},
|
|
|
move_backward_param: {
|
|
|
jsonConfig: {
|
|
|
"type": "move_backward_param",
|
|
|
- "message0": "向后移动 %1 次",
|
|
|
+ "message0": "%1 向后移动 %2 次",
|
|
|
"args0": [
|
|
|
+ {
|
|
|
+ "type": "field_image",
|
|
|
+ "src": xianqianImage,
|
|
|
+ "width": 16,
|
|
|
+ "height": 16,
|
|
|
+ "alt": "向后移动多次"
|
|
|
+ },
|
|
|
{
|
|
|
"type": "field_number",
|
|
|
"name": "PARAM",
|
|
|
@@ -90,67 +106,70 @@ const availableBlocks = {
|
|
|
"nextStatement": null,
|
|
|
"colour": 230,
|
|
|
"tooltip": "控制角色向后移动指定次数",
|
|
|
- "helpUrl": "",
|
|
|
- "icon": {
|
|
|
- "src": "▶",
|
|
|
- "width": 16,
|
|
|
- "height": 16,
|
|
|
- "alt": "向后移动多次"
|
|
|
- }
|
|
|
+ "helpUrl": ""
|
|
|
},
|
|
|
isGeneral: true
|
|
|
},
|
|
|
turn_left: {
|
|
|
jsonConfig: {
|
|
|
"type": "turn_left",
|
|
|
- "message0": "向左转",
|
|
|
+ "message0": "%1 向左转",
|
|
|
+ "args0": [
|
|
|
+ {
|
|
|
+ "type": "field_image",
|
|
|
+ "src": xianqianImage,
|
|
|
+ "width": 16,
|
|
|
+ "height": 16,
|
|
|
+ "alt": "向左转"
|
|
|
+ }
|
|
|
+ ],
|
|
|
"previousStatement": null,
|
|
|
"nextStatement": null,
|
|
|
"colour": 230,
|
|
|
"tooltip": "控制角色向左转",
|
|
|
- "helpUrl": "",
|
|
|
- "icon": {
|
|
|
- "src": "◀",
|
|
|
- "width": 16,
|
|
|
- "height": 16,
|
|
|
- "alt": "向左转"
|
|
|
- }
|
|
|
+ "helpUrl": ""
|
|
|
},
|
|
|
isGeneral: true
|
|
|
},
|
|
|
turn_right: {
|
|
|
jsonConfig: {
|
|
|
"type": "turn_right",
|
|
|
- "message0": "向右转",
|
|
|
+ "message0": "%1 向右转",
|
|
|
+ "args0": [
|
|
|
+ {
|
|
|
+ "type": "field_image",
|
|
|
+ "src": xianqianImage,
|
|
|
+ "width": 16,
|
|
|
+ "height": 16,
|
|
|
+ "alt": "向右转"
|
|
|
+ }
|
|
|
+ ],
|
|
|
"previousStatement": null,
|
|
|
"nextStatement": null,
|
|
|
"colour": 230,
|
|
|
"tooltip": "控制角色向右转",
|
|
|
- "helpUrl": "",
|
|
|
- "icon": {
|
|
|
- "src": "▶",
|
|
|
- "width": 16,
|
|
|
- "height": 16,
|
|
|
- "alt": "向右转"
|
|
|
- }
|
|
|
+ "helpUrl": ""
|
|
|
},
|
|
|
isGeneral: true
|
|
|
},
|
|
|
turn_around: {
|
|
|
jsonConfig: {
|
|
|
"type": "turn_around",
|
|
|
- "message0": "向后转",
|
|
|
+ "message0": "%1 向后转",
|
|
|
+ "args0": [
|
|
|
+ {
|
|
|
+ "type": "field_image",
|
|
|
+ "src": xianqianImage,
|
|
|
+ "width": 16,
|
|
|
+ "height": 16,
|
|
|
+ "alt": "向后转"
|
|
|
+ }
|
|
|
+ ],
|
|
|
"previousStatement": null,
|
|
|
"nextStatement": null,
|
|
|
"colour": 230,
|
|
|
"tooltip": "控制角色向后转",
|
|
|
- "helpUrl": "",
|
|
|
- "icon": {
|
|
|
- "src": "◀▶",
|
|
|
- "width": 16,
|
|
|
- "height": 16,
|
|
|
- "alt": "向后转"
|
|
|
- }
|
|
|
+ "helpUrl": ""
|
|
|
},
|
|
|
isGeneral: true
|
|
|
},
|
|
|
@@ -158,36 +177,42 @@ const availableBlocks = {
|
|
|
pickup_item: {
|
|
|
jsonConfig: {
|
|
|
"type": "pickup_item",
|
|
|
- "message0": "拾取物品",
|
|
|
+ "message0": "%1 拾取物品",
|
|
|
+ "args0": [
|
|
|
+ {
|
|
|
+ "type": "field_image",
|
|
|
+ "src": xianqianImage,
|
|
|
+ "width": 16,
|
|
|
+ "height": 16,
|
|
|
+ "alt": "拾取物品"
|
|
|
+ }
|
|
|
+ ],
|
|
|
"previousStatement": null,
|
|
|
"nextStatement": null,
|
|
|
"colour": 30,
|
|
|
"tooltip": "尝试拾取当前位置的物品",
|
|
|
- "helpUrl": "",
|
|
|
- "icon": {
|
|
|
- "src": "👆",
|
|
|
- "width": 16,
|
|
|
- "height": 16,
|
|
|
- "alt": "拾取物品"
|
|
|
- }
|
|
|
+ "helpUrl": ""
|
|
|
},
|
|
|
isGeneral: true
|
|
|
},
|
|
|
use_item: {
|
|
|
jsonConfig: {
|
|
|
"type": "use_item",
|
|
|
- "message0": "使用物品",
|
|
|
+ "message0": "%1 使用物品",
|
|
|
+ "args0": [
|
|
|
+ {
|
|
|
+ "type": "field_image",
|
|
|
+ "src": xianqianImage,
|
|
|
+ "width": 16,
|
|
|
+ "height": 16,
|
|
|
+ "alt": "使用物品"
|
|
|
+ }
|
|
|
+ ],
|
|
|
"previousStatement": null,
|
|
|
"nextStatement": null,
|
|
|
"colour": 30,
|
|
|
"tooltip": "在当前位置使用物品",
|
|
|
- "helpUrl": "",
|
|
|
- "icon": {
|
|
|
- "src": "👇",
|
|
|
- "width": 16,
|
|
|
- "height": 16,
|
|
|
- "alt": "使用物品"
|
|
|
- }
|
|
|
+ "helpUrl": ""
|
|
|
},
|
|
|
isGeneral: true
|
|
|
},
|
|
|
@@ -195,8 +220,15 @@ const availableBlocks = {
|
|
|
pause: {
|
|
|
jsonConfig: {
|
|
|
"type": "pause",
|
|
|
- "message0": "暂停 %1 秒",
|
|
|
+ "message0": "%1 暂停 %2 秒",
|
|
|
"args0": [
|
|
|
+ {
|
|
|
+ "type": "field_image",
|
|
|
+ "src": xianqianImage,
|
|
|
+ "width": 16,
|
|
|
+ "height": 16,
|
|
|
+ "alt": "暂停"
|
|
|
+ },
|
|
|
{
|
|
|
"type": "field_number",
|
|
|
"name": "SECONDS",
|
|
|
@@ -210,49 +242,49 @@ const availableBlocks = {
|
|
|
"nextStatement": null,
|
|
|
"colour": 0,
|
|
|
"tooltip": "让角色在原地停留指定的秒数",
|
|
|
- "helpUrl": "",
|
|
|
- "icon": {
|
|
|
- "src": "⏸",
|
|
|
- "width": 16,
|
|
|
- "height": 16,
|
|
|
- "alt": "暂停"
|
|
|
- }
|
|
|
+ "helpUrl": ""
|
|
|
},
|
|
|
isGeneral: false
|
|
|
},
|
|
|
play_sound: {
|
|
|
jsonConfig: {
|
|
|
"type": "play_sound",
|
|
|
- "message0": "声音",
|
|
|
+ "message0": "%1 声音",
|
|
|
+ "args0": [
|
|
|
+ {
|
|
|
+ "type": "field_image",
|
|
|
+ "src": xianqianImage,
|
|
|
+ "width": 16,
|
|
|
+ "height": 16,
|
|
|
+ "alt": "声音"
|
|
|
+ }
|
|
|
+ ],
|
|
|
"previousStatement": null,
|
|
|
"nextStatement": null,
|
|
|
"colour": 160,
|
|
|
"tooltip": "自动触发特效提示音,并根据当前方格类型执行相应操作",
|
|
|
- "helpUrl": "",
|
|
|
- "icon": {
|
|
|
- "src": "🔊",
|
|
|
- "width": 16,
|
|
|
- "height": 16,
|
|
|
- "alt": "声音"
|
|
|
- }
|
|
|
+ "helpUrl": ""
|
|
|
},
|
|
|
isGeneral: false
|
|
|
},
|
|
|
construct: {
|
|
|
jsonConfig: {
|
|
|
"type": "construct",
|
|
|
- "message0": "修建",
|
|
|
+ "message0": "%1 修建",
|
|
|
+ "args0": [
|
|
|
+ {
|
|
|
+ "type": "field_image",
|
|
|
+ "src": xianqianImage,
|
|
|
+ "width": 16,
|
|
|
+ "height": 16,
|
|
|
+ "alt": "修建"
|
|
|
+ }
|
|
|
+ ],
|
|
|
"previousStatement": null,
|
|
|
"nextStatement": null,
|
|
|
"colour": 160,
|
|
|
"tooltip": "修建处理",
|
|
|
- "helpUrl": "",
|
|
|
- "icon": {
|
|
|
- "src": "🔧",
|
|
|
- "width": 16,
|
|
|
- "height": 16,
|
|
|
- "alt": "修建"
|
|
|
- }
|
|
|
+ "helpUrl": ""
|
|
|
},
|
|
|
isGeneral: false
|
|
|
}
|
|
|
@@ -314,15 +346,15 @@ const availablePythonGenerators = {
|
|
|
return 'move_forward()\n';
|
|
|
},
|
|
|
move_forward_param: function(block) {
|
|
|
- const times = block.getFieldValue('PARAM');
|
|
|
- return `move_forward(${times})\n`;
|
|
|
+ const stepCount = block.getFieldValue('PARAM');
|
|
|
+ return `move_forward(${stepCount})\n`;
|
|
|
},
|
|
|
move_backward: function(block) {
|
|
|
return 'move_backward()\n';
|
|
|
},
|
|
|
move_backward_param: function(block) {
|
|
|
- const times = block.getFieldValue('PARAM');
|
|
|
- return `move_backward(${times})\n`;
|
|
|
+ const stepCount = block.getFieldValue('PARAM');
|
|
|
+ return `move_backward(${stepCount})\n`;
|
|
|
},
|
|
|
turn_left: function(block) {
|
|
|
return 'turn_left()\n';
|
|
|
@@ -450,11 +482,10 @@ export function registerJavaScriptGenerators(blocklySpecialBlocks = []) {
|
|
|
// 确保blocklySpecialBlocks始终是数组
|
|
|
blocklySpecialBlocks = Array.isArray(blocklySpecialBlocks) ? blocklySpecialBlocks : [];
|
|
|
// 遍历所有可用生成器
|
|
|
- for (const [blockName, generatorFunction] of Object.entries(availableGenerators)) {
|
|
|
- // 检查对应的积木是否为通用积木或允许的特殊积木
|
|
|
- const blockConfig = availableBlocks[blockName];
|
|
|
- if (blockConfig && (blockConfig.isGeneral || blocklySpecialBlocks.includes(blockName))) {
|
|
|
- javascriptGenerator.forBlock[blockName] = generatorFunction;
|
|
|
+ for (const [blockName, generatorFunc] of Object.entries(availableGenerators)) {
|
|
|
+ // 如果是通用生成器,或者是允许的特殊生成器对应的生成器,则注册
|
|
|
+ if (availableBlocks[blockName].isGeneral || blocklySpecialBlocks.includes(blockName)) {
|
|
|
+ javascriptGenerator.forBlock[blockName] = generatorFunc;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -472,12 +503,11 @@ export function registerJavaScriptGenerators(blocklySpecialBlocks = []) {
|
|
|
export function registerPythonGenerators(blocklySpecialBlocks = []) {
|
|
|
// 确保blocklySpecialBlocks始终是数组
|
|
|
blocklySpecialBlocks = Array.isArray(blocklySpecialBlocks) ? blocklySpecialBlocks : [];
|
|
|
- // 遍历所有可用Python生成器
|
|
|
- for (const [blockName, generatorFunction] of Object.entries(availablePythonGenerators)) {
|
|
|
- // 检查对应的积木是否为通用积木或允许的特殊积木
|
|
|
- const blockConfig = availableBlocks[blockName];
|
|
|
- if (blockConfig && (blockConfig.isGeneral || blocklySpecialBlocks.includes(blockName))) {
|
|
|
- pythonGenerator.forBlock[blockName] = generatorFunction;
|
|
|
+ // 遍历所有可用生成器
|
|
|
+ for (const [blockName, generatorFunc] of Object.entries(availablePythonGenerators)) {
|
|
|
+ // 如果是通用生成器,或者是允许的特殊生成器对应的生成器,则注册
|
|
|
+ if (availableBlocks[blockName].isGeneral || blocklySpecialBlocks.includes(blockName)) {
|
|
|
+ pythonGenerator.forBlock[blockName] = generatorFunc;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -490,8 +520,9 @@ export function registerPythonGenerators(blocklySpecialBlocks = []) {
|
|
|
|
|
|
/**
|
|
|
* 初始化Blockly工作区
|
|
|
- * @param {Object} options - 初始化选项
|
|
|
- * @returns {Blockly.Workspace} - 初始化后的Blockly工作区
|
|
|
+ * @param {HTMLElement} blocklyDiv - Blockly容器元素
|
|
|
+ * @param {HTMLElement} toolbox - 工具箱元素
|
|
|
+ * @returns {Blockly.WorkspaceSvg} - Blockly工作区实例
|
|
|
*/
|
|
|
export function initBlockly(options = {}) {
|
|
|
// 应用中文配置
|