[Scratch 3.0] 自作ブロックで使えるブロックタイプ４種類とサンプル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/01a05ef7-619b-18ec-ac35-a49edada9aaa.png)

[元記事](https://medium.com/@hiroyuki.osaki/scratch-3-block-types-you-can-develop-and-samples-191b0d769b91)

Scratch 3.0向けに自作オリジナルブロックを開発することができます。
Scratch 3.0を利用しているたくさんの人に自分のブロックを使ってもらう事ができます。
もちろんすでに通常のScratch 3.0にも「ブロック定義」というものがあるのですが、もっと自由度が高い、もしくは独自デバイスと連携するような少しギークなことをしようとするなら、オリジナルブロックを開発するとよいです。

開発方法・環境準備方法は[前の記事](https://qiita.com/Hiroyuki_OSAKI/items/a46e1c881d3aed4661f7)で述べましたので、参照してください。

さて、本題ですが、**開発できるブロックのタイプがいくつかあります**。

**自分が作りたい中身に合わせて、ブロックのタイプを選ぶ**と良いと思います。
なぜならScratch 3.0はブロックのタイプで**見た目や触り心地が変わり、大きくユーザエクスペリエンスが変わる**からです。

例えば、`COMMAND`ブロックを使用すると、1行のコマンドを実行させるような処理に向いています。

他にも色々なタイプがありますので、さっそく見ていきましょう。

# 目次：全タイプ（★が一つのものは詳細は今回省きます）

1. `COMMAND`タイプ　★★★★ 超基本
2. `REPORTER`タイプ　★★★　基本
3. `BOOLEAN`タイプ　★★　ちょっと上級
4. `HAT`タイプ ★★　ちょっと上級
5. `EVENT`タイプ　★　上級
6. `CONDITIONAL`タイプ　★上級
7. `LOOP`タイプ　★上級
8. `BUTTON`タイプ　★上級

# 1) `COMMAND`タイプのブロック

`COMMAND`タイプは一番簡単でよく使われるブロックのタイプです。

`COMMAND`は１つの関数処理を実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/583064b5-9407-fef3-aaa3-4cfcad7f9339.png)

どんなふうに使うかと言うと、こんなふうに別のブロックを上下につないで使います。

ブロックは**上から下に向けて順番に実行されます**。ですから、この`COMMAND`ブロックは上のブロックの処理が終わったあとに実行されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/aeaa86e3-9892-4ee2-0e3b-26ecdbbc92c6.png)

では、開発する場合にはどうするかですが、まずは**ブロックの定義**を書きます。
`COMMAND`ブロックの定義はこのように書きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/2d826dab-bd36-1817-2e9d-806b6aa64028.png)

`{}`にくくられている範囲が定義です。`blockType`は`BlockType.COMMAND`とかく必要があります。

`text`には、ブロックの顔にもなるところに表示したい文字列で、好きに記載します。ただし、一つだけルールがあり、`[●●]`と書くとその●●は入力を受け付ける特別な場所と認識されます。

`opcode`は後で説明するこのブロックの大事な処理の実装の名前です。

では次に、ブロックの処理を実装します。
先ほど`opcode`に書いたのと同じ名前の関数の中に、ブロックの処理を書いていきます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/87c51ea0-b88c-73d0-1e5a-3310cdc7f1bf.png)

`args`という引数を受け取ることができます。`args`の下には、ブロック定義の`text`で指定した入力の名前の変数が入っています。

上の例では、一番簡単な処理として、`TEXT`という値を入力として受け取って、それをログ（デバッグ画面で表示できる）に書き出す、ということをしています。ここは自由に自分の処理を書いてください。

# 2) `REPORTER`タイプのブロック

`REPORTER`も基本的なブロックです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/4c3ae678-45a2-fdbb-96f9-f9985439e548.png)

`REPORTER`は、値を作ることに特化しています。値というと、`String`型や`Integer`型などさまざまな値を扱うことができます。ただし、基本的には`String`で扱われると考えておいたほうがよいかもしれません。

**`REPORTER`が出す値は、ほかのブロックに入れる**ことができます。
`COMMAND`ブロックの入力として入れることもできます。また、`REPORTER`ブロックの入力にも入れることができるので、こんな感じに何段にも入れ子を作れたりもします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/0f806867-2b80-de29-c961-6315f7c8f9e1.png)

では作ってみたいと思います。

`REPORTER`ブロックの定義は、このようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/3e9af1dd-e186-0ded-fb51-6592203ee328.png)

`blockType`は`BlockType.REPORTER`になります。それ以外はだいたい`COMMAND`と同じです。

では、ブロックの実装はどうなるでしょうか。`opcode`に指定された名前の関数はこうなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/b221dbc3-98fb-de4e-0df1-b6845b2cc9fc.png)

`COMMAND`ブロックと違い、`REPORTER`ブロックは**`return`文を使って値を最後に返しています**。

この値が、ブロックで作った値となります。
このブロックでは`Argument TEXT is （ここにTEXTという入力の文字列を入れる）`という文章(`String`型)を作っています。

# 3) `BOOLEAN`タイプのブロック

`BOOLEAN`タイプは`REPORTER`の特殊なバージョンと言えます。

`boolean`という、以下の２つしかバリエーションがない値だけを扱うという特殊なバージョンです。

- `true` (真[しん]といい、「結果が正しい」ことを表します)か
- `false` (偽[ぎ]といい、「結果が間違っている」ことを表します)か

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/22686235-1155-2eea-0588-0488cd02eec5.png)

すこしだけトリッキーな使い方ができます。
というのも、ほかのブロックに入れるときにいくつかのパターンがあるのです。

簡単な使い方は、`BOOLEAN`を入力として受け付けるほかのブロックにくっつける場合です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/b3191ef4-e5c8-24cf-4934-4a05a5af5aff.png)

こういうブロックは最初から入力部分が`<=>`みたいな形になっているので、つながるなーと分かります。
つないでみると、見た目どおり確かにつながります。

次ですが、ほかのブロックにもくっつけることができます。それは、`String`などほかの値を受け取るようなブロックにくっつける場合です。
下の例を見ると、入力の形が`○`のようになっていてつながらさそうなのですが、下のようにつながってしまいます。これはこれで正しいのです（これで処理が間違わないように`Cast`をしなければなりませんが）


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/11dcc80c-9848-f559-a080-8d1dbdb2caf5.png)

では、ブロックを作ってみます。

ブロックの定義はこうなります。ほとんど`REPORTER`と同じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/b1f77bad-333c-7143-22a9-f5783fba6e9d.png)

大事なのは実装です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/625136eb-e204-79d8-31b5-a45de038a113.png)

ちゃんと**`boolean`つまり`true`か`false`を返さなければいけません**。

# 4) `HAT`タイプのブロック

`HAT`タイプは**イベント（なにか変わったことが起きたこと）に気づく**ために必要なブロックです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/da1c3bf0-ea69-bfee-f1de-6606f2c24346.png)

例えば、上の絵のように別の`send`ブロックから送られたイベントを受け取って、処理を始める、といったときに使います。

このブロックには複雑な処理を書くわけではなくて、**何が変わったか**についてを指定してあげる必要があります。

さっそくブロックの定義はこうなります。この基本的な内容も`COMMAND`と同じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/62c35a1c-ccad-1bba-9827-73c76e93fc1d.png)

このブロックの実装はこうなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/0bdd787c-22e4-42ba-48ee-b941132305d3.png)

`HAT`の処理は`hat1`という関数に書いてあります。
内容は、`send1`という別のブロックで変更した値`changed`に気づく、という処理を書いています。`changed`が変わったときに`return rtn`のところで`true`の値を返して終わります。

大事なのは、`hat1`という関数は常に呼び続けられて、その値が変わったときに次のブロックを実行していくということです。しかも少し癖があって、`false`から`true`になったときだけ、イベントとして検知することができます。

なので、下の絵のように`hat1`が変わった場合には、２回イベントが検知されることになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/33a55f47-1106-14e4-1421-7373f0855086.png)

ここで少し困ったことになる場合があります。
例えばキーを押し続けたりしてScratchキャットを右に動かし続けるようなプログラムがありますよね。こういうふうに、イベントを連続で検知するときに失敗したりするのです。
なぜかというと、`true`を返し続けてしまうからです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/b95510a7-7148-502d-3c78-97e3c2412bd1.png)

`true`を連続で返すと、Scratchは「値が`false`から`true`になったわけではない」と判断してイベント検知してくれません。したがって、上の絵のように`true`がずっと出ているのに、イベント検知は１回になってしまいます。

じゃあ、どうするかというと、たとえばこんなふうに必ず一回`false`に戻るように`hat1`を実装変更することで対応できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96277/950d047c-52f9-bda7-2211-454c7fd503f1.png)

# 結論：ブロックタイプをうまく選ぼう

さて、４つのブロックタイプ、`COMMAND`、`REPORTER`、`BOOLEAN`、`HAT`を使ってブロックが作れるようになりました。目的に応じてうまくタイプを選ぶと、とても使いやすいブロックができると思います。これで、あなたのオリジナルブロックが将来、みんなに使ってもらうようになる日が来るかもしれません。

# リファレンス

[Scratch 3.0 GitHubレポジトリの拡張機能ドキュメント](https://github.com/LLK/scratch-vm/blob/develop/docs/extensions.md)