Edited at

Scratch 3.0でオリジナルブロックをつくろう


Scratch 3.0が正式版となって登場!

(メッセージ)おとなむけのきじです。こんど、こどもむけのきじをかきます。まっててね。

(更新)2019/1/16 Scratchで楽しく学ぶ アート&サイエンスの著者の石原さん@champierre 直々にコメントをいただいて、しかも修正箇所もご指摘いただきました。ありがとうございました!びっくりしたー

2019/3/31 @mkisono から最新版に合わせたコメントいただきsrc/extension-support/extension-manager.js修正!ありがとうござました!

2019/8/19 公開方法を追記しました。

2019/1/3、ついにScratch 3.0がでました。

Scratch

https://scratch.mit.edu/

かっこいいですね~!

2019-01-04 (5).png

2020年からの小学校プログラミング必修化に向けて、タブレット対応も完了したことになります。

これで導入の拍車がかかるScratch 3.0。

実装もかなり洗練されていて、もうこどもの勉強道具の領域を超えています

Scratch 3.0の重要ポイントと、オリジナルブロック追加方法について説明します。


3.0の重要ポイント (使う人向け)


  • ブラウザだけで動作 (これは従来通り)


  • Flashなしで動作可能に :thumbsup:
    したがってiPad、タブレット、iPhoneなどどこでも使用可能

  • チュートリアルが豊富に。
    マニュアルなしでもとにかく触りながら覚えられる。

  • デザインが段違いに洗練された。


3.0の重要ポイント (Scratch3.0内実装)


  • 内部はNode.js。TypeScriptではない生のJavaScript。

  • 画面はReactで実装されていて、各パーツでちゃんとコンポーネント化されている。すばらしい。

  • ES2015(constなど)には対応。しかしES2017(asyncなど)は未対応。webpackでコンパイルしている。

  • 拡張機能の仕様のたたき台が公開されている。2から少し変わったらしい。


  • npmパッケージを導入可能。拡張機能にも利用できるらしい(公式には書いてないが私はできた)


オリジナルブロックをつくってみよう

わたしは、2つの方法でブロックをつくりました。


  • 方法1.感触を試すだけ

  • 方法2.ちゃんとしたオリジナルブロックを作る


    • 自分の開発環境を作る

    • ブロックを実装

    • GUI側を更新




方法1.お試しサイトで感触を試す


この方法の特徴


  • 雰囲気はつかめるので、入りとしてはよい

  • 単一JavaScriptファイルのみ読み込み可能

  • ブラウザリロードで消えてしまう

  • npmパッケージ利用不可


やりかた

以下の記事の通りに実施します。

すると、正式版ではないサイトで自作JavaScriptを読み込ませることで、オリジナルブロック追加の感触が試せます。

うまくいけば10分ほどでできます。

http://blog.champierre.com/1133

利用する正式版ではないサイト

https://sheeptester.github.io/scratch-gui/


試した結果

image.png

できた!!


方法2. ちゃんとしたオリジナルブロックをつくる

教えていただいたのは公式Wikiさんのツイート。


この方法の特徴


  • 開発環境が手に入る

  • npmなどを使い、自由にNode.jsの拡張機能を作れる

  • まだ開発済みブロックを共有・公開するまでには至らない
    公開はScratch開発チームにて実施。共有はこれからやり方が提供されるそう。公式Wiki


やりかた

公式Wikiの記事に記載の通りに実施しますが、途中から私のアレンジです。

今回は、ただ入力の文字列をログに吐き出すブロックを作ります。


1) 開発環境を整えます

2つのgitプロジェクト(scratch-vm, scratch-gui)をクローンします。

両方とも開発する部分があるので、同時にコンパイルできるように、scratch-guiを親として、scratch-vmを子供としてリンクして使用します。

## 以下yarn はnpmでも可能

$ git clone --depth 1 https://github.com/llk/scratch-vm.git
$ git clone --depth 1 https://github.com/llk/scratch-gui.git
$ cd scratch-vm && yarn install && yarn link
## 上記でscratch-vmの依存パッケージがダウンロードされる
## 最後にnpmのリンクに追加される。
$ cd scratch-gui && yarn link scratch-vm && yarn install
## 上記で、scratch-vmを子供としてリンクし、ほかのパッケージをダウンロードする。

起動を確認します。

$ cd scratch-gui

$ yarn start

コンパイルが完了したら、

http://localhost:8601

にアクセスして画面を見てみます。

image.png

いけましたね。


2) ブロックを実装します

今回はWikiに従い「newblocks」という新しい拡張機能を追加する。

拡張機能は複数のブロックを含むことができるが、今回のnewblocksは1つのブロックのみを持つ。

追加(★)および更新(★★)するファイルは以下。(scratch-vmのソースツリー)

.

├── LICENSE
├── node_modules
├── package.json
├── package-lock.json
├── README.md
├── src
│   ├── blocks
│   ├── dispatch
│   ├── engine
│   ├── extensions
│   │   ├── scratch3_ev3
│   │   ├── scratch3_newblocks 【★これを追加する】
│   │   │   └── index.js【★これを追加する → ファイル1】
│   │   ├── 【その他いくつか】
│   │   └── scratch3_wedo2
│   ├── extension-support
│   │   ├── argument-type.js
│   │   ├── extension-manager.js 【★★これを更新する → ファイル2】
│   │   └── 【その他いくつか】
│   ├── import
│   ├── index.js
│   ├── io
│   ├── playground
│   ├── serialization
│   ├── sprites
│   ├── util
│   └── virtual-machine.js
├── test
├── TRADEMARK
├── webpack.config.js
├── yarn-error.log
└── yarn.lock

さて、1の手順でダウンロードしてきたscratch-vm内に、ソースコードを追加・更新します。

ファイル1src/extensions/scratch3_newblocks/index.jsは、ブロックの処理を記載します。


src/extensions/scratch3_newblocks/index.js

const ArgumentType = require('../../extension-support/argument-type');

const BlockType = require('../../extension-support/block-type');
const Cast = require('../../util/cast');
const log = require('../../util/log');

class Scratch3NewBlocks {
constructor (runtime) {
this.runtime = runtime;
}

getInfo () {
return {
id: 'newblocks',
name: 'New Blocks',
blocks: [
{
opcode: 'writeLog',
blockType: BlockType.COMMAND,
text: 'log [TEXT]',
arguments: {
TEXT: {
type: ArgumentType.STRING,
defaultValue: "hello"
}
}
}
],
menus: {
}
};
}

writeLog (args) {
const text = Cast.toString(args.TEXT);
log.log(text);
}
}

module.exports = Scratch3NewBlocks;


ファイル2src/extension-support/extension-manager.jsは、ブロックの一覧です。

そこに先ほどのscratch3_newblocksを追加します。


src/extension-support/extension-manager.js


const builtinExtensions = {
coreExample: () => require('../blocks/scratch3_core_example'),
pen: () => require('../extensions/scratch3_pen'),
wedo2: () => require('../extensions/scratch3_wedo2'),
music: () => require('../extensions/scratch3_music'),
microbit: () => require('../extensions/scratch3_microbit'),
text2speech: () => require('../extensions/scratch3_text2speech'),
translate: () => require('../extensions/scratch3_translate'),
videoSensing: () => require('../extensions/scratch3_video_sensing'),
speech2text: () => require('../extensions/scratch3_speech2text'),
ev3: () => require('../extensions/scratch3_ev3'),
makeymakey: () => require('../extensions/scratch3_makeymakey'),
gdxfor: () => require('../extensions/scratch3_gdx_for'), 【★最後のコンマを追加】
newblocks: () => require('../extensions/scratch3_newblocks')【★ この行を追加】
};

これで、ブロックの実装は完了です。おめでとうございます。


3) GUIを更新します

ユーザがブロックを追加できるようにGUIを変更しましょう。

GUIの左下の「+」ボタンを押すと、メニューが出てきます。これをライブラリといいます。

image.png

ここに2)でつくったブロック処理を追加します。

scratch-guiのフォルダ内のsrc/lib/libraries/extensions/index.jsxの最後に以下を追加します。


src/lib/libraries/extensions/index.jsx


【略】

import wedoMenuImage from './peripheral-connection/wedo/wedo-small.svg';
import wedoButtonImage from './peripheral-connection/wedo/wedo-button-illustration.svg';

// 冒頭importが続く部分に以下の2行を追加
import newBlockImage from './newblocks/newblocks.png';
import newBlockButtonImage from './newblocks/newblocks-small.png';

export default [
{
【中略】
connectingMessage: (
<FormattedMessage
defaultMessage="Connecting"
description="Message to help people connect to their WeDo."
id="gui.extension.wedo2.connectingMessage"
/>
),
helpLink: 'https://scratch.mit.edu/wedo'

}
// ここから下を追加
,
{
name: 'NewBlocks',
extensionId: 'newblocks',
collaborator: 'Me',
iconURL: newBlockImage,
insetIconURL: newBlockButtonImage,
description: (
<FormattedMessage
defaultMessage="New blocks."
description="my block"
id="gui.extension.newblocks.description"
/>
),
featured: true,
disabled: false,
internetConnectionRequired: true,
bluetoothRequired: false,
helpLink: 'https://scratch.mit.edu/wedo'

}
// ここまでを追加
];


メニュー用の画像を追加します。

追加する場所として先程のsrc/lib/libraries/extensions/の下にnewblocksというフォルダを追加します。

メニューの背景用の画像として、同じフォルダに600 x 372のサイズのnewblocks.pngファイルを追加します。

newblocks.png

メニューのアイコン用画像として、同じフォルダに180 x 180のサイズのnewblocks-small.pngファイルを追加します。

newblocks-small.png

こんなフォルダ構成になっていればOK.

.

├── LICENSE
├── package.json
├── prune-gh-pages.sh
├── README.md
├── src
│   ├── components
│   ├── containers
│   ├── css
│   ├── examples
│   ├── index.js
│   ├── lib
│   │   ├── alerts
│   │   ├── libraries
│   │   │   └── extensions/
│   │   │   │   ├── index.jsx 【★ 更新された】
│   │   │   │   ├── newblocks【★追加された】
│   │   │   │   │   ├── newblocks.png 【★ 追加された】
│   │   │   │   │   └── newblocks-small.png 【★ 追加された】
│   │   │   │   └── 【その他】
│   │   ├── log.js
│   ├── playground
│   ├── reducers
│   └── test.js
├── static
├── test
├── TRADEMARK
├── translations
├── webpack.config.js
├── yarn-error.log
└── yarn.lock

ここまできたら最後。1)の最後と同じように、GUIを起動します。

これでコンパイルが走り、うまく2)のブロックと3)のGUIがコンパイルされれば成功。

$ cd scratch-gui

$ yarn start


結果:

メニューを開くと、自分で作った拡張機能「NewBlocks」が表示されるので、クリックします。

image.png

そうすると、元の画面のアイコンの一番下にNewBlocksが追加されていて、その中に、log(hello)があります。

image.png

この新しいブロックをプログラムに追加して、旗(スタート)ボタンをおすと、右下のデバッグ画面に

vm hello

と出ています。

デバッグ画面は、ブラウザごとに違いますので、出し方はこちらw3schoolを参考にしてください。ChromeならF12キーで出てきます。

目的の「ログに書き出す」を達成したことがわかります。

ブロックの中の文字を変えてみてスタートを押してもちゃんと値が変わることが確認できますよね。

ちゃんとブロックが動いていますね。


公開する

すでにscratchのソースコードには公開するための仕掛けがついています。

やり方はこちらのWikiに書いてあります。

私の場合は、GitHub上でもとのレポジトリ(LKK/scratch-gui)をフォークして自分のレポジトリ(onelittlenightmusic/scratch-gui)を作成します。

上記で作成した開発環境のoriginを自分のレポジトリに変更します。

git remote add origin2 https://github.com/onelittlenightmusic/scratch-gui.git

git remote remove origin
git remote rename origin2 origin

yarn run build

yarn run deploy

すると、自分のレポジトリのなかで作成されたgithub pagesに公開されます。

(私の場合はhttps://onelittlenightmusic.github.io/scratch-gui/)

image.png


まとめ

できました。これまで私いろんな記事書きましたが、これまでになかった興奮です。

Scratch 3.0のブロックが作れてしまいました。しかもこんなにかんたんに。

さて、私のほうでは、バックエンドにGraphQLサーバを置いておき、apollo-linkを使って天気を取得するブロックも作ってみたりしてます。

image.png

Scratch猫くんがリアルタイムにNew yorkの天気を教えてくれますよ。

このやり方はまた別の機会に。


残課題


  • せっかく作ったブロックはみなリリースしたいはず。GUIとVMにまたがるこの修正箇所をいかにリリースできるしかけにするのか。Scratch teamが鋭意検討中とのこと。期待しましょう。私自身は、node-REDのようにnpmパッケージとして公開すれば、動的にロードできる、というふうになっているとベストと思います。


備考

Scratch自体は今8歳の娘が昔から結構触ってたのですが、それでもこれまでベータ版で公開されていたScratch 3.0を触らず嫌い。。これからは積極的に触ってもらおうと思います。