Help us understand the problem. What is going on with this article?

ScratchX でレポーターブロック(Reporter blocks)を作る

More than 3 years have passed since last update.

ScratchX で非同期のコマンドブロック(Asynchronous command)を作る の続きです。


今回はレポーターブロックを作ります。

レポーターブロックとはこんな感じのやつです。

image

緑のブロックのように白い穴に入れた値を計算して新しい値を別のブロックに渡したり、青のブロックのように別のブロックに値を渡したりするブロックです。

事前準備

前回の ScratchX の Extension をローカルで開発する環境を整える で作った環境をベースにして作業をしていきます。

環境が無い方は是非記事を参考にして整えてみてください。

同期レポーターブロックを作る

同期レポーターブロックはすぐに値を別のブロックに渡せる場合に使います。

先ほど貼り付けた画像のブロックは全て同期レポーターブロックです。

今回は三角形の面積を求めるレポーターブロックを作ってみたいと思います。

完成イメージ

完成イメージはこんな感じです。

底辺 ◯ 高さ ◯ の三角系の面積 というブロックが今回作るものです。

image

Extension を作る

前回作った log_extension.js を編集します。

主に

  1. triangle_area 関数を追加
  2. descriptor のところを修正

をやっているだけです。 書くのが面倒だったらまるごとコピペしちゃってください。

log_extension.js
(function(ext) {

  // コメントは補足の説明なので書かなくてもいいです

  // Extension が終了するときに呼ばれる
  // 今は特に何もしない
  ext._shutdown = function() {};

  // Extension の状態を返す
  // デバイスが繋がっていないときにはエラーを返したりする
  // ---
  // 返す値, 表示される色, 意味
  //      0,          red, error
  //      1,       yellow, not ready
  //      2,        green, ready
  // ---
  // 今回はデバイスなどは使用しないので常に準備完了
  // ということで 2 を返します。
  ext._getStatus = function() {
    return {status: 2, msg: 'Ready'};
  };

  ext.triangle_area = function(a, b) {
    return a * b / 2;
  };

  // wait 秒待ってから str を表示するブロック
  ext.wait_log = function(wait, str, callback) {
    setTimeout(function() {
      alert(str);
      callback();
    }, wait * 1000);
  };

  // この関数がブロック処理になります。
  ext.log = function(str) {
    // ログを出力するだけ
    alert(str);
  };

  // ブロックをどういう風に表示するかを書きます
  // ここの書き方は結構難しいので今は説明しません
  var descriptor = {
    blocks: [
      [' ', 'log %s', 'log', 'sample log'],
      ['w', 'wait %s secs and log %s', 'wait_log', 1, 'sample log'],
      ['r', '底辺 %n, 高さ %n の三角系の面積', 'triangle_area', 2, 3]
    ]
  };

  // Scratch に作ったブロックを登録します
  ScratchExtensions.register('Log Extension', descriptor, ext);
})({});

diff はこんな感じです。

diff --git a/src/log_extension.js b/src/log_extension.js
index 349ac6e..0f48439 100644
--- a/src/log_extension.js
+++ b/src/log_extension.js
@@ -20,6 +20,10 @@
     return {status: 2, msg: 'Ready'};
   };

+  ext.triangle_area = function(a, b) {
+    return a * b / 2;
+  };
+
   // wait 秒待ってから str を表示するブロック
   ext.wait_log = function(wait, str, callback) {
     setTimeout(function() {
@@ -39,7 +43,8 @@
   var descriptor = {
     blocks: [
       [' ', 'log %s', 'log', 'sample log'],
-      ['w', 'wait %s secs and log %s', 'wait_log', 1, 'sample log']
+      ['w', 'wait %s secs and log %s', 'wait_log', 1, 'sample log'],
+      ['r', '底辺 %n, 高さ %n の三角系の面積', 'triangle_area', 2, 3]
     ]
   };

保存したら実際に ScratchX に読み込ませて使ってみます。

ScratchX で使ってみる

まずはローカルサーバーを起動します。

前回と同じ手順です。

terminal でpackage.json のあるディレクトリに移動して npm start を実行します。

そしたら http://scratchx.org/?url=http://localhost:8080/log_extension.js をブラウザで開いて I understand, continue という緑色のボタンを押します。

image

すると今作った 底辺 ② 高さ ③ の三角系の面積 というブロックが追加されていると思います。

image

ちょっと複雑ですが、こんな感じにブロックを組んで実行してみましょう。

image

実行すると以下の様な感じで喋ります。

image

image

同期レポーターブロックに関しては以上です。

非同期レポーターブロックを作る

お次は非同期のレポーターブロックを作ります。

非同期レポーターブロックはすぐに値を別のブロックに渡せない場合に使います。

例えばインターネットで通信して値を取得するものだったり、値の取得に時間のかかるセンサーを使う場合などです。

今回はインターネット上で公開されている OpenWeatherMap というサービスを使って東京の気温を取得するブロックを作ってみたいと思います。

今回作るこのブロックは値(気温)を取得するためにインターネットで通信する必要があるので、値の取得に少し時間がかかります(数ミリ秒程度)。

こういった時間がかかる処理を同期レポーターブロックで作ってしまうと他のブロックの動作に影響を与えてしまうため非同期で行います。具体的には処理が完了するまで他のブロックの動作を止めてしまいます。

完成イメージ

完成イメージはこんな感じです。

東京の気温 というブロックが今回作るブロックです。

image

Extension を作る

今回も log_extension.js を編集します。

主に

  1. temp_of_tokyo 関数を追加
  2. descriptor のところを修正

をやっているだけです。 書くのが面倒だったらまるごとコピペしちゃってください。

log_extension.js
(function(ext) {

  // コメントは補足の説明なので書かなくてもいいです

  // Extension が終了するときに呼ばれる
  // 今は特に何もしない
  ext._shutdown = function() {};

  // Extension の状態を返す
  // デバイスが繋がっていないときにはエラーを返したりする
  // ---
  // 返す値, 表示される色, 意味
  //      0,          red, error
  //      1,       yellow, not ready
  //      2,        green, ready
  // ---
  // 今回はデバイスなどは使用しないので常に準備完了
  // ということで 2 を返します。
  ext._getStatus = function() {
    return {status: 2, msg: 'Ready'};
  };

  // 東京の気温を取得する
  ext.temp_of_tokyo = function(callback) {

    var param = {
      q: "tokyo",
      appid: "ddd98c6a715c25fd4a3b45e64c34bb10",
      units: "metric"
    };

    // 気象情報 API にアクセス
    $.get("http://api.openweathermap.org/data/2.5/weather", param, function(data) {
      callback(data.main.temp);
    });
  };

  ext.triangle_area = function(a, b) {
    return a * b / 2;
  };

  // wait 秒待ってから str を表示するブロック
  ext.wait_log = function(wait, str, callback) {
    setTimeout(function() {
      alert(str);
      callback();
    }, wait * 1000);
  };

  // この関数がブロック処理になります。
  ext.log = function(str) {
    // ログを出力するだけ
    alert(str);
  };

  // ブロックをどういう風に表示するかを書きます
  // ここの書き方は結構難しいので今は説明しません
  var descriptor = {
    blocks: [
      [' ', 'log %s', 'log', 'sample log'],
      ['w', 'wait %s secs and log %s', 'wait_log', 1, 'sample log'],
      ['r', '底辺 %n, 高さ %n の三角系の面積', 'triangle_area', 2, 3],
      ['R', '東京の気温', 'temp_of_tokyo']
    ]
  };

  // Scratch に作ったブロックを登録します
  ScratchExtensions.register('Log Extension', descriptor, ext);
})({});

diff はこんな感じです。

diff --git a/src/log_extension.js b/src/log_extension.js
index 0f48439..380878e 100644
--- a/src/log_extension.js
+++ b/src/log_extension.js
@@ -20,6 +20,21 @@
     return {status: 2, msg: 'Ready'};
   };

+  // 東京の気温を取得する
+  ext.temp_of_tokyo = function(callback) {
+
+    var param = {
+      q: "tokyo",
+      appid: "ddd98c6a715c25fd4a3b45e64c34bb10",
+      units: "metric"
+    };
+
+    // 気象情報 API にアクセス
+    $.get("http://api.openweathermap.org/data/2.5/weather", param, function(data) {
+      callback(data.main.temp);
+    });
+  };
+
   ext.triangle_area = function(a, b) {
     return a * b / 2;
   };
@@ -44,7 +59,8 @@
     blocks: [
       [' ', 'log %s', 'log', 'sample log'],
       ['w', 'wait %s secs and log %s', 'wait_log', 1, 'sample log'],
-      ['r', '底辺 %n, 高さ %n の三角系の面積', 'triangle_area', 2, 3]
+      ['r', '底辺 %n, 高さ %n の三角系の面積', 'triangle_area', 2, 3],
+      ['R', '東京の気温', 'temp_of_tokyo']
     ]
   };

ScratchX で使ってみる

ローカルサーバーを起動して http://scratchx.org/?url=http://localhost:8080/log_extension.js をブラウザで開いて I understand, continue という緑色のボタンを押します。

そしたら 東京の気温 というブロックがあると思います。 無かったらなにか間違えているのでプログラムを見なおしてください。

下の画像を参考にしてブロックを組んで実行すると吹き出しに現在の気温が表示されます。

下の画像では 5.95 度ですが、実行するときによって気温は変わるので表示も変わります。

image


まとめ

今回は同期レポーターブロックと非同期レポーターブロックを作りました。

同期レポーターブロックでは自分の好きな計算式を使って計算した結果を別のブロックに渡せるので、複雑な計算もブロック1つでできるようになるので便利だと思います。

非同期レポーターブロックはインターネット(Web API)を使って値を取得する場合などの時間がかかる処理の場合に使います。 ちょっと上級者向けの機能ですが使えるようになるとたくさんのことができるようになります。

残すはハットブロックのみですが、その前に今まで説明をしてこなかった descriptor の部分について説明したいと思います。

  var descriptor = {
    blocks: [
      [' ', 'log %s', 'log', 'sample log'],
      ['w', 'wait %s secs and log %s', 'wait_log', 1, 'sample log'],
      ['r', '底辺 %n, 高さ %n の三角系の面積', 'triangle_area', 2, 3],
      ['R', '東京の気温', 'temp_of_tokyo']
    ]
  };

という部分です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away