Vue实现图形化积木式编程(十)
Blockly自定义块
- 路由
- 下一篇
- 历史回顾
- Babylon.js部分
- Blockly部分
- 前言
- 最终实现效果
- 本文实现效果
- 完整代码
- 代码分解
- 0.代码块前置知识
- 0.1 汉化
- 0.2 预置块
- 0.3 不同样式块含义
- 0.3.1 连接方式
- 0.3.2 输入方式
- 0.3.2 输入类型
- 0.4 代码块构建代码块
- 1. 自定义块
- 1.1 定义块行为
- 1.2 注册块
- 1.2 定义块生成代码
- 1.3 引入块
- 后续计划
- Blockly
- 开源项目GitHub链接
- 资源下载链接
- 你的点赞是我继续编写的动力
路由
下一篇
- Vue实现图形化积木式编程(十一) ---- Blockly插件使用
历史回顾
Babylon.js部分
- Vue实现图形化积木式编程(一) ---- Babylon.js基础场景搭建
- Vue实现图形化积木式编程(二) ---- Babylon.js加载模型到场景中
- Vue实现图形化积木式编程(三) ---- Babylon.js点击拖拽移动模型
- Vue实现图形化积木式编程(四) ---- Babylon.js实现碰撞效果
- Vue实现图形化积木式编程(五) ---- Babylon.js自定义启动界面
- Vue实现图形化积木式编程(六) ---- Babylon.js相机控制与相机动画
- Vue实现图形化积木式编程(七) ---- babylonjs-gui 按钮实现
- Vue实现图形化积木式编程(八) ---- 将3d界面放入可拖动窗口中
Blockly部分
- Vue实现图形化积木式编程(九) ---- Blockly代码块编辑区域基本场景搭建
前言
前段时间想要做一个web端的图形化积木式编程(类似少儿编程)的案例,网上冲浪了一圈又一圈,终于技术选型好,然后代码一顿敲,终于出来了一个雏形。
TIPS:该案例设计主要参考iRobot Coding,只用做学习用途,侵删。
https://code.irobot.com/#/
最终实现效果
本文实现效果
- Blockly自定义块
完整代码
- Blockly自定义块
<template><div id="blockly"><!-- 工作区 --><div id="blocklyDiv" ref="blocklyDiv" style="height: 500px; width: 800px;"></div><button style="position: fixed;left: 50px;top: 10px;" @click="block2code">生成代码</button><!-- 代码显示区 --><div style="background-color: lightgrey;width: 800px;text-align: left"><pre v-html="code?code:'请点击生成代码按钮'"></pre></div><button style="position: fixed;left: 150px;top: 10px;" @click="runCode">执行代码</button></div>
</template><script>
import Blockly from 'blockly'
import BlocklyJS from 'blockly/javascript';
import './customBlock'
export default {name: "blocklyClass1",data() {return {code:'',options: {horizontalLayout: true,//工具箱水平toolboxPosition: "end",//工具箱在底部toolbox: {"kind": "flyoutToolbox","contents": [{"kind": "block","type": "while_program_start",},{"kind": "block","type": "move",},{"kind": "block","type": "turn",},{"kind": "block","type": "arc"},{"kind": "block","type": "draw"},{"kind": "block","type": "pencilcolor"},{"kind": "block","type": "controls_repeat_ext"},{"kind": "block","type": "controls_whileUntil"},{"kind": "block","type": "controls_for"},{"kind": "block","type": "controls_if"},{"kind": "block","type": "logic_compare"},{"kind": "block","type": "logic_operation"},{"kind": "block","type": "logic_negate"},{"kind": "block","type": "logic_boolean"},{"kind": "sep","gap": "32"},{"kind": "block","blockxml": "<block type='math_number'><field name='NUM'>10</field></block>"},{"kind": "block","type": "math_arithmetic"},{"kind": "block","type": "math_single"},{"kind": "block","type": "text"},{"kind": "block","type": "text_length"},{"kind": "block","type": "text_print"},{"kind": "block","type": "variables_get"},{"kind": "block","type": "variables_set"},]}}}},mounted() {Blockly.inject(this.$refs.blocklyDiv, this.options);},methods:{/*** block代码块转为代码*/block2code(){this.code = BlocklyJS.workspaceToCode(this.$refs.blocklyDiv.workspace)},/*** 执行生成代码*/runCode(){if(!this.code){alert('请先点击生成代码');return}eval(this.code)},},
}
</script><style scoped>
#blockly {position: absolute;left: 50px;top: 50px;bottom: 0;width: calc(100vw - 50px);height: calc(100vh - 50px);display: flex;flex-direction: column;
}
</style>
- 封装的自定义块方法 - customBlock.js
import * as Blockly from 'blockly/core'import * as hans from 'blockly/msg/zh-hans'Blockly.setLocale(hans);//汉化/*** 自定义组件注册*/
Blockly.defineBlocksWithJsonArray([//事件{"type": "while_program_start","message0": "当程序运行 %1 %2","args0": [{"type": "input_dummy"},{"type": "input_statement","name": "while_content"}],"previousStatement": null,"nextStatement": null,"colour": "#609FD6","strokeColour": "#4088C8","tooltip": "123","helpUrl": "1"},//指令{"type": "move","message0": "移动 %1 CM","args0": [{"type": "field_input","name": "move_distance","text": "50"}],"previousStatement": null,"nextStatement": null,"colour": "#F7D233","strokeColour": "#CCAD2B","tooltip": "","helpUrl": ""},{"type": "turn","message0": "向 %1 %2","args0": [{"type": "field_dropdown","name": "dirction","options": [["左转","0"],["右转","1"]]},{"type": "field_angle","name": "degree","angle": 90}],"previousStatement": null,"nextStatement": null,"colour": "#F7D233","strokeColour": "#CCAD2B","tooltip": "","helpUrl": ""},{"type": "arc","message0": "弧形 %1 %2 ,半径 %3 CM","args0": [{"type": "field_dropdown","name": "dirction","options": [["向左","0"],["向右","1"]]},{"type": "field_angle","name": "degree","angle": 90},{"type": "field_number","name": "radius","value": 50,"min": 1,"max": 100}],"previousStatement": null,"nextStatement": null,"colour": "#F7D233","strokeColour": "#CCAD2B","tooltip": "","helpUrl": ""},{"type": "draw","message0": "设置 %1","args0": [{"type": "field_dropdown","name": "pencilState","options": [[{"src": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFIGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjEtMDgtMjNUMTE6Mzk6NTQrMDg6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTA4LTIzVDExOjUxOjAxKzA4OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIxLTA4LTIzVDExOjUxOjAxKzA4OjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmVkZGRkMGNlLTU4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","width": 50,"height": 50,"alt": "pencil down"},"1"],[{"src": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFIGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjEtMDgtMjNUMTE6NDA6MTErMDg6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTA4LTIzVDExOjUyOjA2KzA4OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIxLTA4LTIzVDExOjUyOjA2KzA4OjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjU3Y2UzN2ViLTQ0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","width": 50,"height": 50,"alt": "pencil up"},"0"]]}],"previousStatement": null,"nextStatement": null,"colour": "#81C679","tooltip": "","helpUrl": ""},{"type": "pencilcolor","message0": "设置笔颜色: 红 %1 绿 %2 蓝 %3","args0": [{"type": "field_number","name": "red","value": 100,"min": 0,"max": 255},{"type": "field_number","name": "green","value": 100,"min": 0,"max": 255},{"type": "field_number","name": "blue","value": 100,"min": 0,"max": 255}],"previousStatement": null,"nextStatement": null,"colour": "#81C679","tooltip": "","helpUrl": ""}]
);/*** 自定义组件生成代码* @param block* @returns {string}*/
Blockly.JavaScript['while_program_start'] = function (block) {blockvar while_content = Blockly.JavaScript.statementToCode(block, 'while_content');var code = 'robot.init();\n'+ while_content +'robot.stop();\n';return code;
};Blockly.JavaScript['move'] = function (block) {var text_move_distance = block.getFieldValue('move_distance');var code = 'robot.move(' + text_move_distance + ');\n';return code;
};Blockly.JavaScript['turn'] = function (block) {var dropdown_dirction = block.getFieldValue('dirction');var angle_degree = block.getFieldValue('degree');var code = 'robot.turn(' + dropdown_dirction + ', ' + angle_degree + ');\n';return code;
};Blockly.JavaScript['arc'] = function (block) {var dropdown_dirction = block.getFieldValue('dirction');var angle_degree = block.getFieldValue('degree');var radius = block.getFieldValue('radius');var code = 'robot.arc(' + dropdown_dirction + ', ' + angle_degree + ',' + radius + ');\n';return code;
};Blockly.JavaScript['draw'] = function (block) {var dropdown_pencilstate = block.getFieldValue('pencilState');var code = 'robot.drawable(' + dropdown_pencilstate + ');\n';return code;
};Blockly.JavaScript['pencilcolor'] = function (block) {var number_red = block.getFieldValue('red') / 255.0;var number_green = block.getFieldValue('green') / 255.0;var number_blue = block.getFieldValue('blue') / 255.0;var code = 'await robot.pencilcolor(' + number_red + ',' + number_green + ',' + number_blue + ');\n';return code;
};
代码分解
自定义块主要分3部分:
1、定义块行为
2、注册块
3、定义块生成代码
4、引入块
0.代码块前置知识
0.1 汉化
import * as hans from 'blockly/msg/zh-hans'
Blockly.setLocale(hans);//汉化
0.2 预置块
Blockly原本已经预置了很多代码块了
逻辑块(logic_compare、logic_operation、logic_negate、logic_boolean)
循环控制块(controls_repeat_ext、controls_whileUntil、controls_if)
数学模块(math_number、math_arithmetic、math_single)
文本模块(text、text_length、text_print)
变量块(variables_get、variables_set)
0.3 不同样式块含义
0.3.1 连接方式
- 上下连接
以javascript为例,在一个事件循环中,代码块会顺序执行(不包含异步代码块),代码块之间就是上下连接方式
let loop = 10//上连接为空,下连接为print
print('hello world')//上连接为赋值语句,下连接为for循环代码块
for(let i = 0; i < 10; i++){...}//上连接为print,下连接为while循环代码块
while(loop){...}//上连接为for循环代码块,下连接为空
- 左连接
左连接可以理解为其为输出
任何值的输出都使用左连接方式,如(数字模块输出数字、文本模块输出文本、逻辑模块输出真假)
0.3.2 输入方式
输入方式,即函数传入的参数
输入的连接方式不一样,日常使用中感觉不出区别
输入可以现在输入的类型,如if、when模块的外接类型输入限制了类型只能为逻辑模块
内联
外接
0.3.2 输入类型
输入的模块的类型分为值输入和块输入
值输入(数字、文本、逻辑)
块输入(代码块)
0.4 代码块构建代码块
- Blockly预置的很多代码块基本符合日常编程的各种使用场景,而其更出色的地方在于其能自定义代码块,而且是通过代码块来生成代码块
官方的自定义代码块链接:自定义代码块构建工具
工具的食用方法可参考大佬文章:blockly构建自定义块及其工具
而在本文中的案例中,控制小车的移动等操作,小车的动作是依次执行的,其实用得最多是上下连接的代码块,该代码块中包含内联的一个或多个值输入:
对应的构造如下:
还有就是小车启动的函数,用的是上下连接的代码块,该代码块中包含外接的块输入:
对应的构造如下,其中空输入只是为了在其中填入文本让其能单独一行显示(好看一点):
1. 自定义块
- 熟悉Block Definition的生成规则当然是最好的了,但是官方提供的代码块构建工具,进行了可视化预览、定义配置、块的生成代码,极大方便了我们的开发。
- 所以自定义块的流程变得很简单啦
1、通过toolbox提供的各种工具块,拖动到编辑区,根据自己的需求区构建自定义块。
2、通过预览区实时查看自定义块是否达到预期效果
3、达到预期效果后,将定义配置区中的JSON配置信息在项目中使用Blockly.defineBlocksWithJsonArray的方法注册自定义块
4、如果是需要生成JavaScript代码,生成代码区选择JavaScript,然后将代码复制到项目中
5、最后就是将代码块引入到toolbox工具箱中
1.1 定义块行为
- 定义块行为就是上面所说的编辑区编辑块规则,或者熟悉Block Definition的同学通过块定义的规则编写JSON格式文本,从而形成块的形状(其形状基本是决定了请行为和功能)
1.2 注册块
- 将定义配置区中的JSON配置信息在项目中使用Blockly.defineBlocksWithJsonArray的方法注册自定义块
/*** 自定义组件注册*/Blockly.defineBlocksWithJsonArray([//当程序运行代码块{"type": "while_program_start","message0": "当程序运行 %1 %2","args0": [{"type": "input_dummy"},{"type": "input_statement","name": "while_content"}],"previousStatement": null,"nextStatement": null,"colour": "#609FD6","strokeColour": "#4088C8","tooltip": "123","helpUrl": "1"},//弧度移动代码块{"type": "arc","message0": "弧形 %1 %2 ,半径 %3 CM","args0": [{"type": "field_dropdown","name": "dirction","options": [["向左","0"],["向右","1"]]},{"type": "field_angle","name": "degree","angle": 90},{"type": "field_number","name": "radius","value": 50,"min": 1,"max": 100}],"previousStatement": null,"nextStatement": null,"colour": "#F7D233","strokeColour": "#CCAD2B","tooltip": "","helpUrl": ""}]);
1.2 定义块生成代码
- 生成代码区选择JavaScript,然后将代码复制到项目中,其中代码已经写好了变量的获取方式,返回值就是生成的代码,我们需要编写的就是返回值的内容。
- 而对于控制小车对象而言,笔者这里统一使用robot对象,然后调用对象中的各种方法,如下面代码中拼接出来的代码为
robot.arc('方向','弧的角度','弧的半径')
/*** 弧度运动自定义块* @param block* @returns {string}*/
Blockly.JavaScript['arc'] = function(block) {var dropdown_dirction = block.getFieldValue('dirction');var angle_degree = block.getFieldValue('degree');var radius = block.getFieldValue('radius');// TODO: Assemble JavaScript into code variable.var code = 'robot.arc(' + dropdown_dirction + ', ' + angle_degree + ',' + radius + ');\n';return code;
};
- 如下代码是控制程序生命周期的,拼接出来的代码为
robot.init();
...(控制小车运动的代码块)
robot.stop();
/***程序启动自定义块* @param block* @returns {string}*/
Blockly.JavaScript['while_program_start'] = function (block) {blockvar while_content = Blockly.JavaScript.statementToCode(block, 'while_content');var code = 'robot.init();\n' +while_content +'robot.stop();\n';return code;
};
1.3 引入块
- 将自定义块引入到toolbox工具箱中
data() {options: {toolbox: {"kind": "flyoutToolbox","contents": [{"kind": "block","type": "while_program_start",},{"kind": "block","type": "arc"},...]}}},
mounted() {//注入选项Blockly.inject(this.$refs.blocklyDiv, this.options);},
后续计划
Blockly
- blockly第三方组件使用
- 小车控制方法的封装
- 接入js-interpreter,步骤运行block块
- …(想到啥写啥)
开源项目GitHub链接
https://github.com/Wenbile/Child-Programming-Web
资源下载链接
- Vue前端源码
- ThinkJS后端源码
你的点赞是我继续编写的动力
Vue实现图形化积木式编程(十)相关推荐
- Vue实现图形化积木式编程(十二)
执行Blockly生成代码 路由 下一篇 历史回顾 Babylon.js部分 Blockly部分 前言 最终实现效果 本文内容 实现思路 问题分析 问题 原因 不优雅解决 优雅解决 完整代码 后续计划 ...
- Vue实现图形化积木式编程(十三)
步骤运行代码块高亮 路由 历史回顾 Babylon.js部分 Blockly部分 前言 最终实现效果 本文内容 实现 1. 安装依赖 2. 简化语法 3. 引入js解析器 4. 运行代码 5. 加入高 ...
- Vue实现图形化积木式编程(十一)
Blockly插件使用 路由 下一篇 历史回顾 Babylon.js部分 Blockly部分 前言 最终实现效果 本文内容 安装 使用 后续计划 开源项目GitHub链接 资源下载链接 你的点赞是我继 ...
- Vue实现图形化积木式编程(一)
Babylon.js基础场景搭建 路由 前言 最终实现效果 本文实现效果 技术选型 1.前端 2.后端 完整代码 代码分解 0.npm安装相关依赖 1.引入模块 2.场景初始化 3.ArcRotate ...
- Vue实现图形化积木式编程(二)
Babylon.js加载模型到场景中 路由 下一篇 历史回顾 前言 最终实现效果 本文实现效果 完整代码 操作分解(Babylon.js模型格式转换与导入) 0.在开源模型网上下载一个模型/自己制作一 ...
- 原创教程:下载和安装“图形化积木Python编程”海龟编辑器
一.简介 Python编辑器是一款界面简单充满童趣的Python编程软件,该软件普遍适用于低龄化用户,帮助培养用户对代码编程的兴趣:众所周知编写代码是比较枯燥的事情,所以学起来更是如此,为解决这一难题 ...
- python积木式编程_TurnipBit—MicroPython开发板:从积木式编程语言开始学作小小创客...
编程.建模.制做动画和游戏--这些当初咱们默认只有成年人玩得转的事情,如今早已经被无数小孩子给颠覆甚至玩出新境界了.热爱科技和动手的"创客"(Maker)如今在全世界都煊赫一时.今 ...
- 竞赛无人机搭积木式编程——以2022年TI电赛送货无人机一等奖复现为例学习(7月B题)
在学习本教程前,请确保已经学习了前4讲中无人机相关坐标系知识.基础飞行控制函数.激光雷达SLAM定位条件下的室内定点控制.自动飞行支持函数.导航控制函数等入门阶段的先导教程. 同时用户在做二次开发自定 ...
- python积木式编程_【发现教育版亮点之美】3D One还能这么玩:“趣味编程”建模让你脑洞大开...
原标题:[发现教育版亮点之美]3D One还能这么玩:"趣味编程"建模让你脑洞大开 "[有奖征文]发现3D One教育版亮点之美"教育版功能文章征集活动已经告一 ...
最新文章
- 正则表达式模式修正符
- 码云gitee最大文件限制
- CentOS7中多台服务器配置SSH免密钥登录
- 全面改进Transformer类预训练模型,自然语言任务超越BERT
- AtCoder 2305 [AGC010D] Decrementing(博弈)
- 训练深度学习_深度学习训练tricks整理1
- 用java实现云计算的两种趋势性方法
- nginx之反向代理服务器
- 乱谈卡巴CCTV黄金时段广告
- (原)使用vectot的.end()报错:iterators incompatible
- php bc 比较,php BC高精确度函数库
- BLOB:大数据,大对象,在数据库中用来存储超长文本的数据,例如图片等
- Linux系统下init进程的前世今生
- 信息系统分析与设计 第三章 信息系统建设概论
- 生产企业全流程生产管控_如何通过创建流程使生产率提高10倍
- xcopy 跳过已经存在的_视频课怎么区分数学一二三?考研英语怎么复习?恋练有词句子部分直接跳过?...
- 物联网毕设分享 STM32 wifi照明控制系统 - 智能路灯(毕设分享)
- 【数学建模】熵值法与多指标评价系统
- 2020春招---飞鱼科技 一面面经
- sja1000 中断_SJA1000PeliCAN模式下自收发问题