10

ファイルで次のブロックを実行しBlocklyました。customBlocks.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ブラウザ(Google Chrome)のコンソールから変数に直接アクセスしようとしましたが、「子ブロック」を取得できましたが、それらの値は取得できませんでした。次のように:

    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 ピクセル移動したかどうかを確認することです。もしそうなら、「わかりました!」というメッセージを表示します。

私の質問

ワークスペースに配置したブロックのインスタンスを作成し、そのインスタンスでピクセル値にアクセスする可能性はありますか?

編集:

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(真); // トップレベルのブロックを取得するには
  • 最上位ブロック リストの繰り返し
  • block = block.nextConnection && block.nextConnection.targetBlock(); // ブロックのサブブロックに「下降」し、それらを反復するには
  • if(block.type=="move_right") ... // 特定のブロック タイプをチェックするには

これが出発点になることを願っていますが、これらの「トリック」について学ぶ最善の方法は、Blockly のソース コードを読むことです。コードは一般的によくコメントされていますが、知る限り、ドキュメントを自動生成する方法はなく、Web でも利用できません。

于 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、それが使用されているかどうかを確認できます (それが openned カテゴリのブロックであるか、それからドラッグされたブロックであるか、使用中の場合)。

于 2016-06-25T21:43:33.140 に答える