Blocks的前世今生
在开始本案例之前,大家先通过下面的小例子,巩固一下Blockly开发者工具的使用。实现如下代码块的设计:
参考答案如下:
一、Plane中raw块的模拟
1. 块的设计
在Block Factory中设计raw代码块的外观,完成设计后点击“Save raw-block”按钮,将新建块保存到Blocks Library中。
2. 块的代码导出
点击Block Exporter选项卡,选择raw-block代码:
修改界面中间部分的Export Setting属性:
- 勾中Block Definition(s)和Generator Stub(s)选项;
- 将二者的Format属性(语言格式),都选为JavaScript;
- 文件的命名,为方便辨认和引用,文件命名时建议采用块名(raw-block)+ b/g的形式,如命名为raw-block-b和raw-block-g。
属性修改完成之后,点击Export按钮即可对部分代码进行下载。导出的代码分两部分,一部分是Block Denifition代码,一部分是Generator Stub代码。
(1)Block Denifition代码
此部分代码,负责控制新建块(raw-blocks)的外观,包括样式、颜色等,最终放在blocks文件夹中。
(2)Generator Stub代码
此部分代码,负责控制新建块(raw-blocks)的代码转换,最终放在generators的对应子文件夹中。
3. html文件的修改
在完成块的代码设计与导出之后,需要将其导入至html文件中,以呈现给用户。
(1)导入raw_block_b文件
<script src="../../blocks/raw_block_b.js"></script>
(2)导入raw_block_g文件
<script src="../../generators/javascript/raw_block_g.js"></script>
(3)导入raw_block_g块
<block type="raw_block"></block>
完成之后保存html文件,并在浏览器中打开,即可看到你所新建的块raw(5)了。
提示:
直接导出的文件放到指定的文件夹下并导入html文件中,可以直接使用;不过保险起见,最好类比其他blocks和generators中的文件,在文件顶部加上相应的“头”文件。 如下是在raw_block_b中添加的代码:
'use strict'; goog.provide('Blockly.Blocks.repeat_times'); // Deprecated goog.provide('Blockly.Constants.repeat_times'); goog.require('Blockly.Blocks'); goog.require('Blockly');
在html文件修改的过程中,应注意raw_block_b、raw_block_g和raw_block插入的位置和顺序,会影响显示的效果,可自行探索尝试。
2. print-py块的设计
1. 块的设计
在Block Factory中设计print-py代码块的外观,完成设计后点击“Save print-py”按钮,将新建块保存到Blocks Library中。
2. 块的代码导出
点击Block Exporter选项卡,选择print-py代码:
修改界面中间部分的Export Setting属性:
- 勾中Block Definition(s)和Generator Stub(s)选项;
- 选择二者的Format属性(语言格式),前者选为JavaScript,后者选为Python;
- 文件的命名,为方便辨认和引用,文件命名时建议采用块名(print-py)+ b/g的形式,如命名为print-py-b和print-py-g。
属性修改完成之后,点击Export按钮即可对部分代码进行下载。导出的代码分两部分,一部分是Block Denifition代码,一部分是Generator Stub代码。
(1)Block Denifition代码
此部分代码,负责控制新建块(print-py)的外观,包括样式、颜色等,最终放在blocks文件夹中。
(2)Generator Stub代码
此部分代码,负责控制新建块(print-py)的代码转换,最终放在generators的对应子文件夹中。
3. html文件的修改
在完成块的代码设计与导出之后,需要将其导入至html文件中,以呈现给用户。
(1)导入print_py_b文件
<script src="../../blocks/print_py_b.js"></script>
(2)导入raw_block_g文件
<script src="../../generators/python/print_py_g.js"></script>
(3)导入raw_block_g块
<block type="print_py"></block>
完成之后保存html文件,并在浏览器中打开,即可看到你所新建的块“打印”了。
4. 优化改进
完成前3步之后,功能已基本实现,现在有3个小任务,对print-py块进行优化。
- (1)print-py代码是否可以与raw代码整合到一个文件中,为什么
- (2)print-py块如何类比print块加上默认阴影
<block type="print_py">
<value name="print_sub"> // value的name为块设计中的value input的name
<shadow type="text">
<field name="TEXT">Test</field>
</shadow>
</value>
</block>
- (3)完善print-py块的其他几种语言的转换功能
3. Repeat-Do块的复现
在Block Factory中设计repeat-do代码块的外观,完成设计后点击“Save repeat-do”按钮,将新建块保存到Blocks Library中。
2. 块的代码导出
可以选择像前两个demo中一样,直接Export代码块对应的代码,不过这里为了方便,直接用raw_block的js文件,复制repeat-do的两部分代码,分别粘贴到raw-block-b.js和raw-block-g.js文件中,保存即可。
3. html文件的修改
在完成块的代码设计与导出之后,需要将其导入至html文件中,以呈现给用户。
(1)raw_block_b和raw_block_g文件已导入,无需重复导入
<script src="../../blocks/raw_block_b.js"></script>
<script src="../../generators/javascript/raw_block_g.js"></script>
(2)导入repeat-do代码块,并加上默认阴影
<block type="repeat_do">
<value name="repeat_times">
<shadow type="math_number">
<field name="NUM">10</field>
</shadow>
</value>
</block>
完成之后保存html文件,并在浏览器中打开,即可看到你所新建的块repeat-do代码块了。
是不是已经分辨不出哪个块是你自己创建的了?
4. 代码转换功能完善
虽然从外观已经很难分辨出哪个是我们自定义的repeat-do代码块了,但是我们并没有给它添加实际的代码转换功能,如下图:
一个repeat-do代码块会有两个“参数”的输入,一个是次数,一个是需要do的语句,它们转换后的JavaScript代码应该为:
for (var count = 0; count < 10; count++) {
window.alert('abc');
}
所以我们参照这个样式,来进行repeat-do自定义块代码的设计:
Blockly.JavaScript['repeat_do'] = function(block) {
var value_repeat_times = Blockly.JavaScript.valueToCode(block, 'repeat_times',Blockly.JavaScript.ORDER_ATOMIC);
var statements_repeat_statement = Blockly.JavaScript.statementToCode(block, 'repeat_statement');
// TODO: Assemble JavaScript into code variable.
var code = 'for(var count=0;count<' + value_repeat_times + ';count++){\n ' + statements_repeat_statement + '}\n';
return code;
};
至此,repeat-do代码块大功告成!