Scratch 3.0が正式版となって登場!
更新
- 2019/1/16 Scratchで楽しく学ぶ アート&サイエンスの著者の石原さん@champierre 直々にコメントをいただいて、しかも修正箇所もご指摘いただきました。ありがとうございました!びっくりしたー
- 2019/3/31 @mkisono から最新版に合わせたコメントいただき
src/extension-support/extension-manager.js
修正!ありがとうござました! - 2019/8/19 公開方法を追記しました。
- 2019/9/7 作れるブロックのタイプ4種類をこちらにまとめました。
2019/1/3、ついにScratch 3.0がでました。
Scratch
https://scratch.mit.edu/
かっこいいですね~!
2020年からの小学校プログラミング必修化に向けて、タブレット対応も完了したことになります。
これで導入の拍車がかかるScratch 3.0。
実装もかなり洗練されていて、もうこどもの勉強道具の領域を超えています。
Scratch 3.0の重要ポイントと、オリジナルブロック追加方法について説明します。
3.0の重要ポイント (使う人向け)
- ブラウザだけで動作 (これは従来通り)
-
Flashなしで動作可能に
したがって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分ほどでできます。
利用する正式版ではないサイト
試した結果
できた!!
方法2. ちゃんとしたオリジナルブロックをつくる
教えていただいたのは公式Wikiさんのツイート。
Japanese Scratch-Wikiには、もっと複雑な例や、拡張機能ライブラリへの追加方法も載っています! 参考にしてください。https://t.co/nNoGUF7IPd
— Japanese Scratch-Wiki (@ScratchWiki_ja) 2019年1月2日
この方法の特徴
- 開発環境が手に入る
- npmなどを使い、自由にNode.jsの拡張機能を作れる
- まだ開発済みブロックを共有・公開するまでには至らない
公開はScratch開発チームにて実施。共有はこれからやり方が提供されるそう。公式Wiki
前提 [2019/09追記]
私が確認した環境は以下2つで、いずれも成功。
pattern 1 | pattern 2 | |
---|---|---|
OS | Windows 10 | MacOS Mojave 10.14.6 |
npm | 6.4.1 | 6.9.0 |
node | 11.2.0 | 12.1.0 |
備考 | WSL(ubuntu 18.04)上です |
やりかた
公式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
コンパイルが完了したら、
にアクセスして画面を見てみます。
いけましたね。
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
は、ブロックの処理を記載します。
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
を追加します。
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の左下の「+」ボタンを押すと、メニューが出てきます。これをライブラリといいます。
ここに2)でつくったブロック処理を追加します。
scratch-gui
のフォルダ内の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ファイルを追加します。
メニューのアイコン用画像として、同じフォルダに180 x 180のサイズの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」が表示されるので、クリックします。
そうすると、元の画面のアイコンの一番下にNewBlocksが追加されていて、その中に、log(hello)
があります。
この新しいブロックをプログラムに追加して、旗(スタート)ボタンをおすと、右下のデバッグ画面に
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/
)
まとめ
できました。これまで私いろんな記事書きましたが、これまでになかった興奮です。
Scratch 3.0のブロックが作れてしまいました。しかもこんなにかんたんに。
さて、私のほうでは、バックエンドにGraphQLサーバを置いておき、apollo-linkを使って天気を取得するブロックも作ってみたりしてます。
Scratch猫くんがリアルタイムにNew yorkの天気を教えてくれますよ。
このやり方はまた別の機会に。
残課題
- せっかく作ったブロックはみなリリースしたいはず。GUIとVMにまたがるこの修正箇所をいかにリリースできるしかけにするのか。Scratch teamが鋭意検討中とのこと。期待しましょう。私自身は、node-REDのようにnpmパッケージとして公開すれば、動的にロードできる、というふうになっているとベストと思います。
備考
Scratch自体は今8歳の娘が昔から結構触ってたのですが、それでもこれまでベータ版で公開されていたScratch 3.0を触らず嫌い。。これからは積極的に触ってもらおうと思います。