Blocklyに基づきビジュアルプログラミングの入門級の実例（一、カスタムブロックの使い方）

#Blocklyとは
Googleのオープンソースの一つです。
普通なコーディングではなく、いろんなブロックを組み合わせてプログラミングをしに行きます。ビジュアルプログラミング言語というジャンルです。
日本では、今までBlocklyに基づいてビジュアルプログラミングを開発する記事がまだ少ない気がします。本章でカスタムBlockの作成から実装までの操作を例としてBlocklyの開発の流れを説明しておきます。

#カスタムBlockを作成
自分のブロックを利用する手順は、大まかに４つに分けられます。
 
- Blocklyの開発ツールで新しいBlockを作成
- Blockの作成と同時、Blockの定義コードとGeneratorが生成
- 新ブロックに機能に合わせGeneratorを編集
- 新ブロックを画面のtoolboxに追加 

まず、プロックを作成しましょう。
[Blocklyの開発ツール](https://blockly-demo.appspot.com/static/demos/blockfactory/index.html)から、以下ようなブロックを作成してみましょう。ブロックの名称は「lightswitch」となっております。
![スクリーンショット 2019-12-21 23.02.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229009/bb8b168b-3059-13b9-eae5-776d2ac8c255.png)
ブロックの作成と同時、ブロックの定義文が生成されています。プロックの定義文がJsonとJavaScriptの二種類があって、本例には、JavaScriptのほうを使って欲しいと思っております。次は、生成されたJavaScript定義コードを「customblocks.js」に保存しましょう。
中身は以下となります。
![スクリーンショット 2019-12-22 9.40.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229009/33e5626f-95d7-24c3-68fd-965ba6d73e88.png)

#Webプロジェクトを作成
カスタムブロックを実装するために、下図ような簡単なWebプロジェクトを作成しましょう。
![スクリーンショット 2019-12-22 8.46.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229009/34c3ef69-f909-a341-0688-42e5b3095c77.png)
プロジェクトの中に、以下のファイルがあります

- circle.html　→　Blocklyを実装したりカスタムブロックの使い方を説明したりするファイル
- customblocks.js　→　カスタムブロックの定義コード、関数を記載するファイル

```html
【circle.html】

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8"/>
    <title> blockly game</title>
    <script src="./blockly/blockly_compressed.js"></script>
    <script src="./blockly/blocks_compressed.js"></script>
    <script src="./blockly/javascript_compressed.js"></script>
    <script src="./blockly/msg/js/en.js"></script>
    <script src="./customblocks.js"></script>
    <style type="text/css">
    	body {
    		background-color: #fff;
    		font-family: sans-serif;
    	}
    	h1 {
    		font-weight: normal;
    		font-size: 140%;
    	}
    	#circle{
    		height: 300px;
    		width: 300px;
    		border-radius:50%;
    		background-color: white;
    		border: solid 1px black;
    		position: absolute;
    		left: 650px;
    		top: 100px;
    	}
    </style>
</head>
<body>
	<!-- button on run code -->
	<p>
		<button onclick="runCode()"> Run Code</button>
	</p>
	<!-- blockly workspace -->
	<div id="blocklyDiv" style="height:480px;width:600px;"></div>
	<xml id="toolbox" style="display:none;">
		<category name="logic">
			<block type="lightswitch">
			</block>
		</category>
	</xml>
	<!-- added to the page -->
	<div id="circle"></div>

<script>
	//set options
	var options = {
	  toolbox: toolbox,
	  collapse: true,
	  comments: true,
	  disable: true,
	  maxBlocks: Infinity,
	  trashcan: true,
	  horizontalLayout: false,
	  toolboxPosition: 'start',
	  css: true,
	  rtl: false,
	  scrollbars: true,
	  sounds: true,
	  oneBasedIndex: true,
	  grid: {
	    spacing: 20,
	    length: 1,
	    colour: '#888',
	    snap: true
	  }
	}

	//put the toolbox in the workspace
	var workspace = Blockly.inject('blocklyDiv', options);
	// take the text generated by the blocks and run it as code
    function runCode() {
		window.LoopTrap = 1000;
		Blockly.JavaScript.INFINITE_LOOP_TRAP = 'if (--window.LoopTrap == 0) throw "Infinite loop.";¥n';
		var code = Blockly.JavaScript.workspaceToCode(workspace);
		Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
		try {
			eval(code);
		} catch (e) {
			alert(e);
		}
    }
</script>
</body>
</html>
```
🌾　[ここ](https://github.com/google/blockly) からBlocklyのライブラリーをダウンロードします

```javascript
【customblocks.js】

//block definition
//light switch block - turn color on or off
Blockly.Blocks['lightswitch'] = {
  init: function() {
    this.appendDummyInput()
        .appendField("Turn")
        .appendField(new Blockly.FieldDropdown([["red","R"], ["blue","B"]]), "lightcolor")
        .appendField(new Blockly.FieldDropdown([["on","T"], ["off","F"]]), "switch");
    this.setColour(270);
 this.setTooltip("");
 this.setHelpUrl("");
  }
};
//block definition
//light switch block - turn color on or off
Blockly.Blocks['lightswitch'] = {
  init: function() {
    this.appendDummyInput()
        .appendField("Turn")
        .appendField(new Blockly.FieldDropdown([["red","R"], ["blue","B"]]), "lightcolor")
        .appendField(new Blockly.FieldDropdown([["on","T"], ["off","F"]]), "switch");
    this.setColour(270);
 this.setTooltip("");
 this.setHelpUrl("");
  }
};
```

#実行結果
「red」、「on」を選択した上で、「Run Code」ボタンを押下すると、下図ように、丸が赤になります。
![スクリーンショット 2019-12-22 10.14.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229009/a25e47d2-b8bf-875d-4aef-bc63c3ae92d2.png)
「blue」、「on」を選択した上で、「Run Code」ボタンを押下すると、下図ように、丸が青になります。
![スクリーンショット 2019-12-22 10.18.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229009/67022803-4391-e7a1-33cf-ffe2f525083a.png)
「off」を選択して、「Run Code」ボタンを押下すると、下図ように、丸が白になります。
![スクリーンショット 2019-12-22 10.18.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229009/9eeb88cc-2ec0-b051-c322-2f322e3bfbe2.png)