在设计使用 Blockly 的应用时,有多种范式可供选择。应尽早考虑这些选择,因为它们会影响用户需要的代码块。
配置
许多 Blockly 应用用于描述配置,而不是可执行程序。配置应用通常通过在工作区中初始化一个根级块来启动。一个很好的例子是 Blockly 开发者工具的“块工厂”标签页:
Blockly.Blocks['factory_base'] = {
init: function() {
this.setDeletable(false);
this.setMovable(false);
this.setEditable(false);
// etc...
}
}
Blockly.serialization.blocks.append({'type': 'factory_base'}, workspace);
这会创建一个不可删除、不可移动的块,用于保存所有用户配置。工作区可以随时序列化,以确定当前配置。
此类应用可能希望自动停用未连接到根块的任何块。这可以通过一行代码来实现:
workspace.addChangeListener(Blockly.Events.disableOrphans);
连续剧
大多数 Blockly 应用都旨在创建串行程序。用户将按顺序执行的代码块堆叠在一起。
工作区上的每个(未停用的)块都将构成程序的一部分。如果有多个块堆栈,则先执行较高的块。(如果两个堆栈的高度大致相同,则优先考虑左侧的堆栈 [在 RTL 模式下为右侧]。)
工作区可以随时导出为可执行代码。此代码可在客户端使用 JavaScript(使用 eval
或 JS 解释器)执行,也可在服务器端使用任何语言执行。
import {javascriptGenerator} from 'blockly/javascript';
var code = javascriptGenerator.workspaceToCode(workspace);
并行计划
有些 Blockly 应用选择并行(而非逐一)执行所有堆叠的块。例如,在音乐应用中,鼓循环与旋律同时运行。
实现并行执行的一种方法是单独为每个块生成代码:
import {javascriptGenerator} from 'blockly/javascript';
var json = Blockly.serialization.workspaces.save(workspace);
// Store top blocks separately, and remove them from the JSON.
var blocks = json['blocks']['blocks'];
var topBlocks = blocks.slice(); // Create shallow copy.
blocks.length = 0;
// Load each block into the workspace individually and generate code.
var allCode = [];
var headless = new Blockly.Workspace();
for (var i = 0; block < topBlocks.length; i++) {
var block = topBlocks[i];
blocks.push(block);
Blockly.serialization.workspaces.load(json, headless);
allCode.push(javascriptGenerator.workspaceToCode(headless));
blocks.length = 0;
}
如果目标语言是 JavaScript,则可以使用 allCode
数组创建多个 JS 解释器以供同时执行。如果目标语言是 Python 之类的语言,则可以将 allCode
数组组装成使用线程模块的单个程序。
与任何并行程序一样,必须针对所有共享资源(例如变量和函数)做出谨慎的决策。
事件驱动型程序
事件处理程序只是由系统(而非程序)调用的函数。这些块可以封装要执行的块堆栈,也可以是位于块堆栈顶部的标头。
有些开发者喜欢在事件块顶部添加“帽子”,使其与其他块区分开来。这不是 Blockly 的默认外观,但可以通过将渲染器常量 ADD_START_HATS
替换为 true
(自定义渲染器 Codelab - 替换常量)来添加,也可以通过添加主题并设置块样式的帽选项来添加。如需详细了解如何设置块的帽子作为主题的一部分,请参阅主题文档中的块样式。
在事件驱动模型中,为程序启动创建处理程序可能也是合理的。在此模型下,工作区中未连接到事件处理程序的任何块都会被忽略,并且不会执行。
在设计使用事件的系统时,请考虑是否可以或是否需要支持同一事件处理程序的多个实例。
工作区布局
从左到右布局屏幕有两种合理的方式。一种方式是从左侧的工具栏开始,中间是工作区,右侧是输出可视化图表。此布局由 Scratch 版本 1 以及 Made with Code 使用。
另一种方式是从左侧的输出可视化图表开始,中间是工具栏,右侧是工作区。Scratch 版本 2 以及大多数 Blockly 应用都使用此布局。
无论哪种情况,工作区都应拉伸以占据可用的屏幕尺寸,因为用户需要尽可能大的空间来编程。从上面的屏幕截图中可以看出,第一个布局在宽屏上的表现不佳,因为用户的代码和输出可视化效果是分开的。而第二种布局则为较大的节目留出了更多空间,同时仍将所有三个部分紧密地放在一起。
对于用户来说,先考虑要解决的问题,然后查看提供的工具,最后才开始编程,这在逻辑上也是合理的。
当然,对于阿拉伯语和希伯来语翻译,整个顺序都需要颠倒。
在某些情况下(例如使用少量简单代码块时),工具箱位于工作区上方或下方可能更合理。Blockly 支持在工具箱中进行水平滚动,以应对这些情况,但应谨慎使用。
建议:将程序可视化图表放置在工具栏旁边。