Blockly を使用するアプリケーションを設計する際には、いくつかのパラダイムから選択できます。これらの選択は、ユーザーが必要とするブロックに影響するため、早い段階で検討する必要があります。
構成
Blockly アプリケーションの多くは、実行可能プログラムではなく、構成を記述するために使用されます。構成アプリは通常、ワークスペースで 1 つのルートレベルのブロックを初期化することから始まります。わかりやすい例として、Blockly Developer Tools の [Block Factory] タブがあります。
Blockly.Blocks['factory_base'] = {
init: function() {
this.setDeletable(false);
this.setMovable(false);
this.setEditable(false);
// etc...
}
}
Blockly.serialization.blocks.append({'type': 'factory_base'}, workspace);
これにより、ユーザーの構成をすべて保持する、削除も移動もできないブロックが作成されます。ワークスペースは、現在の構成を特定するためにいつでもシリアル化できます。
このようなアプリケーションでは、ルートブロックに接続されていないブロックを自動的に無効にしたい場合があります。これは、次の 1 行で実現できます。
workspace.addChangeListener(Blockly.Events.disableOrphans);
シリアル プログラム
Blockly アプリケーションのほとんどは、シリアル プログラムを作成するように設計されています。ユーザーはブロックを積み重ねて、順番に実行します。
ワークスペース上の(無効になっていない)すべてのブロックがプログラムの一部を構成します。ブロックのスタックが複数ある場合は、上にあるものから順に実行されます。(2 つのスタックの高さがほぼ同じ場合は、左側のスタック(RTL モードでは右側)が優先されます)。
ワークスペースはいつでも実行可能コードにエクスポートできます。このコードは、JavaScript(eval
または JS インタープリタを使用)でクライアントサイドで実行することも、任意の言語でサーバーサイドで実行することもできます。
import {javascriptGenerator} from 'blockly/javascript';
var code = javascriptGenerator.workspaceToCode(workspace);
並列プログラム
Blockly アプリケーションによっては、ブロックのすべてのスタックを順次ではなく並行して実行することを選択します。たとえば、メロディーと同時にドラム ループが実行される音楽アプリなどです。
並列実行を実装する方法の 1 つは、各ブロックのコードを個別に生成することです。
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 - 定数をオーバーライドする)か、テーマを追加してブロック スタイルでハット オプションを設定することで追加できます。テーマの一部としてブロックにハットを設定する方法については、テーマのドキュメントのブロック スタイルをご覧ください。
イベント駆動型モデルでは、プログラム開始のハンドラを作成することも理にかなっています。このモデルでは、イベント ハンドラに接続されていないワークスペースのブロックは無視され、実行されません。
イベントを使用するシステムを設計する場合は、同じイベント ハンドラの複数のインスタンスをサポートすることが可能か、望ましいかを検討します。
ワークスペースのレイアウト
画面を左から右にレイアウトする妥当な方法は 2 つあります。1 つの方法では、左側にツールバー、中央にワークスペース、右側に出力ビジュアライゼーションが表示されます。このレイアウトは、Scratch のバージョン 1 と Made with Code で使用されています。
もう 1 つの方法では、左側に出力ビジュアライゼーション、中央にツールバー、右側にワークスペースが表示されます。このレイアウトは、Scratch のバージョン 2 とほとんどの Blockly アプリケーションで使用されています。
いずれの場合も、ワークスペースは利用可能な画面サイズに合わせて拡大される必要があります。ユーザーは、できるだけ広いスペースでプログラミングを行う必要があります。上のスクリーンショットからわかるように、最初のレイアウトではユーザーのコードと出力の可視化が分離されているため、ワイド画面でのパフォーマンスが低下します。一方、2 つ目のレイアウトでは、3 つのセクションを近くに配置したまま、大きなプログラム用のスペースを確保できます。
また、ユーザーが最初に解決しようとしている問題を検討し、提供されているツールを確認してから、プログラミングを開始するという流れも理にかなっています。
もちろん、アラビア語とヘブライ語の翻訳では、順序全体を反転する必要があります。
シンプルなブロックを少数使用する場合など、ツールボックスをワークスペースの上または下に配置するのが妥当な場合もあります。Blockly は、このような場合にツールボックスの水平スクロールをサポートしていますが、慎重に使用する必要があります。
推奨事項: プログラムの可視化をツールバーの横に配置します。