CodePenを使わずにブロック追加
前回の記事
前回は,ひとまずBlocklyが動かせるか確認するために基本的な動きを確認した.ただ,ここからは実装の都合上CodePenを使わないこととする.
CodePenのメリットとしては,index.htmlの結果を見ながら出来る,共有が楽というものであったが,VScodeのプレビューを使用すれば前者は問題ないし,共有もGitHubで十分である.ブラウザであるCodePenで行うとローカルのファイルを使うのが難しかったので手法を変更した.
今回の目標
自分で設計した言語に合わせてBlocklyで置くことができるブロックを変更していく.
一旦は,"play(60, 0.5);" のようにplay関数を表現できるようなものを作成.
ブロック作成
このサイトを一旦参考にしてみる.
Blockly Developer Toolsを使用するらしい.
デベロッパーツールの説明とデモのURLがあったが,簡単に眺めても使い方がわからないため,使い方を調べ次のサイトに.
(2018年の記事)
ブロックデザイン
1.Blockly Developer Toolsを開く
2.「Block Factory」タブをクリック(普通にリンク先飛んだらデフォで選択される)
![](https://assets.st-note.com/img/1698923883370-ATpd8q0Z4g.png?width=1200)
3.緑のブロックの左にある「Input」から「dummy input」を,「Field」から「text」を持ってきて次のように設定し,ブロックの名前を表現させる.
![](https://assets.st-note.com/img/1698923883025-XSL0odUROi.png?width=1200)
4.inputとして次のように引数を追加する.
![](https://assets.st-note.com/img/1698923881172-rEe3xuWwME.png?width=1200)
5.引数が縦に並んでいるのを横にするために,「automatic」を「inline」に変更する.
![](https://assets.st-note.com/img/1698923881432-CYTCBQSZWb.png?width=1200)
6.左のブロックに接続出来るように,「no connections」を「top+bottom connections」に変更する.
7.tooltipとして関数の説明を記述する.
![](https://assets.st-note.com/img/1698924851393-Yeq3sdrX2K.png?width=1200)
8.「Save "play"」ボタンをクリックする.
ブロックをエクスポート
1.「Block Exporter」タブをクリック
2.「play」ブロックのチェックボックスをONにする.
![](https://assets.st-note.com/img/1698923882661-g4b3yn38hi.png?width=1200)
3.次のように「Export Settings」を設定する.
![](https://assets.st-note.com/img/1698924724871-LQavLLRb4C.png?width=1200)
4.「Export」ボタンを押してダウンロード.
![](https://assets.st-note.com/img/1698924890908-73ulB34s7Z.png?width=1200)
ブロック組み込み
変換コードの追加
play.jsを編集し,次の5行目のようにブロックから変換するコードを記述する.(元はcode = '…'となっている)
![](https://assets.st-note.com/img/1699095677380-n1kMdoDJF5.png?width=1200)
index.htmlにブロック読み込み
![](https://assets.st-note.com/img/1698925514146-j62gpk98ad.png)
script.jsは,CodePenを使うのを辞めたのでそこのJSで書いていたもの.
![](https://assets.st-note.com/img/1698925578714-twsPdX4ej2.png?width=1200)
これでtoolboxにplayブロックを追加できた.
![](https://assets.st-note.com/img/1698926164371-xgYp7VTHCK.png?width=1200)
コードの反映
問題把握
参考にしたサイトによると,ここまで行うとブロックを配置した時にコードが自動で記述されるらしいのだが,なぜか置いても反映されない
![](https://assets.st-note.com/img/1699252925520-roLkzU16AA.png?width=1200)
反映されないだけならまだしも,playブロックを置いた後に置いたブロックについても反応しなくなってしまう.
![](https://assets.st-note.com/img/1699253018547-Vo9C9aoIyw.png?width=1200)
ただし,playブロックを配置から削除すると元から入っていたブロックに関しては上手く反映される.
![](https://assets.st-note.com/img/1699253088384-qhs5PAxFzs.png?width=1200)
テストの値は0です,のブロックはネットから拾って新しく追加したブロックなのにこちらは動作する.
![](https://assets.st-note.com/img/1699253185463-bzW8i8KgaX.png?width=1200)
この真似をしてindex.htmlに直接play.jsとplay_block.jsの内容を記述したが,相変わらずコードが反映されなかった.
ORDER_NONEとかいうのがわからなかったから調べたら,カッコの順序みたいな話だった.
![](https://assets.st-note.com/img/1699258038268-kxdWxGL5rq.png?width=1200)
playの方でも同じ要領で括弧について記述してみたけど結果は変わらず.
![](https://assets.st-note.com/img/1699254002771-Jn7K2ecdPJ.png?width=1200)
入力をブロックはめじゃなくしてみたがどっちみち動作しなかった.
custom_testをcustom_test.jsとcustom_test_block.jsの二つのファイルにしてplayと同じように置いてみたらこっちは正しく動作する.
ということはplayとか側に問題がある.
解決策
generatorの方の先頭のところを変えたら反映されるようになった.
![](https://assets.st-note.com/img/1699258618470-Mg5WQMpjfe.png?width=1200)
javascript.javascriptGenerator.forBlock
から
Blockly.JavaScript
に変更した.
ORDER_NONEを入れると,playブロックを他のブロックの下につけた時に"99,"という余計なものが表示されてしまうので消した.
最終的なものは
Blockly.JavaScript['play'] = function(block, generator) {
var number_note_no_ = block.getFieldValue('Note No.');
var number_during = block.getFieldValue('during');
// TODO: Assemble javascript into code variable.
var code = 'play(' + number_note_no_ + ', ' + number_during + ');\n';
return code;
};
GitHubのリポジトリ
追記
入力の制約
![](https://assets.st-note.com/img/1700050522580-e0NSWASgAl.png?width=1200)
play関数の第一引数は(0を含む)自然数になってほしいので,次のようにして制約をつける.
![](https://assets.st-note.com/img/1700051170039-yWWhHkW4S7.png?width=1200)
Blockly.Blocks['play'] = {
init: function() {
this.appendDummyInput()
.appendField("play")
.appendField("Note No.(int)")
.appendField(new Blockly.FieldNumber(0, 0, Infinity, 1), "Note No.")
.appendField("during(double)")
.appendField(new Blockly.FieldNumber(0, 0), "during");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(0);
this.setTooltip("ノートナンバーの音をduringの間流す");
this.setHelpUrl("");
}
};
Blockly.FieldNumber()の引数にInfinity, 1 が追加されている.
これを適用すると,欄の中に小数で書いてもエンターを押すと四捨五入されるようになる.
![](https://assets.st-note.com/img/1700051464019-WvbmV4iAHL.png)
![](https://assets.st-note.com/img/1700051532547-uEheFA9q3N.png)