10

BlocklycustomBlocks.js文件中完成了以下块:

Blockly.Blocks['move_right'] = {
  init: function() {
    this.appendValueInput("PIXELS")
        .setCheck("Number")
        .appendField("move to right");
    this.setInputsInline(true);
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(290);
    this.setTooltip('');
    this.setHelpUrl('http://www.example.com/');
  }
};

Blockly.JavaScript['move_right'] = function(block) {
  var value_pixels = Blockly.JavaScript.valueToCode(block, 'PIXELS', Blockly.JavaScript.ORDER_ATOMIC);
  // TODO: Assemble JavaScript into code variable.
  var codeMoveRight = "$(\"#moveDiv\").animate({\n " + 
                        "left: \"+=" + value_pixels + "px\"\n" +
                      "},1000);\n";  
  return codeMoveRight;
};

div根据您在其上设置的像素数量,将 a向右移动。您必须在math_number块内放置一个块move_right以放置要移动的像素数量。

我的html文件中有一个workspace注入的变量Blockly workspace

var workspace = Blockly.inject('blocklyDiv',
              {toolbox: document.getElementById('toolbox')});

我想做的事

它是在块已显示在 Blockly 的工作区上时从 JavaScript 中检索此数量的像素,而不是之前。

我试过的

  • 我直接尝试从我的兄弟(谷歌浏览器)的控制台访问该workspace变量,并且可以获得“子块”但不是它们的值。如下:

    console.log(workspace.topBlocks_[0].childBlocks_);
    
  • 我还尝试将工作区转换为 dom,然后转换为文本:

    var xml = Blockly.Xml.workspaceToDom(workspace);
    var xml_text = Blockly.Xml.domToText(xml); 
    console.log(xml_text);
    

    在这里我可以看到“子块”的值,我的意思是math_number块,它存储在文本中,但我不知道如何获取它。

为什么我要实现这一目标?

因为我想要的是检查用户是否向右移动了 300 像素。如果是这样,那么我将显示一条消息,其中我将输入“你明白了!”。

我的问题

是否有可能制作我放在工作区上的那个 Block 的实例,然后使用该实例访问它的像素值?

编辑:

我也可以获得left@Oriol所说的价值:

$('#moveDiv').css('left');

但我没有把它放在这里,因为它使用的属性Jquery(这根本不重要,因为它也是一个不错的选择,但不是预期的那样)。Block我的意图是在将它放在之后获取一个实例,Blockly workspace以便以后随时使用它。

4

2 回答 2

8

有一种方法setWarningText来显示这种警告。您可以按如下方式修改您的生成器:

Blockly.JavaScript['move_right'] = function(block) {
    var value_pixels = Blockly.JavaScript.valueToCode(block, 'PIXELS', Blockly.JavaScript.ORDER_ATOMIC);
    // TODO: Assemble JavaScript into code variable.
    var codeMoveRight = "$(\"#moveDiv\").animate({\n " + 
                    "left: \"+=" + value_pixels + "px\"\n" +
                  "},1000);\n";

    // You can show a blockly warning
    if( value_pixels >= 300 ) block.setWarningText("You get it!");

    // Or you can store its value elsewere...
    // myExternalVar = value_pixels;

    return codeMoveRight;
};

这将在块本身中显示为警告图标。

无论如何,如果你想“记住”这个value_pixels变量,我相信更简单的方法是在生成器中进行,如上所示。您始终可以将其存储在可从您的自定义函数访问的外部变量中。

编辑:

如果出于其他目的需要遍历块结构,可以使用:

  • Blockly.mainWorkspace.getTopBlocks(true); // 获取顶层块
  • 对顶级块列表的迭代
  • block = block.nextConnection && block.nextConnection.targetBlock(); // “下降”到块的子块中,然后遍历它们
  • if(block.type=="move_right") ... // 检查特定的块类型

我希望这会给你一个起点,但了解这些“技巧”的最好方法是阅读 Blockly 源代码。即使代码通常得到很好的注释,AFAIK 也无法自动生成文档,并且它在网络上也不可用。

于 2016-04-11T08:08:54.123 回答
0

我知道这个问题有点老了,但是如果您仍然需要更细粒度的访问,您应该使用块IDs(每个块都有一个唯一的ID)。

而且,要获取块元素,不要忘记定义其输入和字段名称,以便您可以引用它们:

示例块:

Blockly.Blocks['my_block_unique_name'] = {
    init: function() {
    this.appendDummyInput("this_input_unique_name_for_this_block")
        .appendField("this block do:")
        .appendField(new Blockly.SomeField(...), "this_field_unique_name_for_this_block");
        this.setColour(60);
        this.setTooltip('this block do something');
    }
    //an crude example, be aware that blocks on fyout list will trigger it, if you did not use the block this block is disposed.
    console.log(this.id); 
};

你可以使用一个事件来获取它ID,将IDs一些有用的信息存储在另一个地方,等等......所以你可以做这样的事情:

mainworkspace = Blockly.mainWorkspace
block = mainworkspace.getBlockById(id);
input = block.getInput("imageInput");
// You can use `setField(newValue,name)` too in a more clean way.
input.removeField("FieldImageButton");
input.appendField(new Blockly.SomeField(...), "this_field_unique_name_for_this_block")

因此,您可以分析该块isInFlyout以查看它是否被使用(如果它是从打开的类别中的块或从中拖出的块,正在使用中),希望它对您和其他人有所帮助。

于 2016-06-25T21:43:33.140 回答