LoginSignup
2
2

More than 3 years have passed since last update.

クジラとネコの親子プログラミング - Docker for Windowsを使ってScratch3.0のオリジナル拡張機能を試してみよう。

Last updated at Posted at 2020-09-07

親子プログラミングはGitとNode.jsが使えることが前提になっている?

小学校でのプログラミング教育の必須化に伴って、子供たちがScratch 3.0に触れる機会も増えるかと思います。そんな中、ブロックをくっつけるだけのお遊びツールだとあなどっていると、次のような連載が始まりました。

「親子でできる!Scratch と AWS を使った "ものづくり" 体験 - 1. 準備 〜 疎通確認編」
2020-09-01
How to be a Developer
金澤 圭

この連載の「2. 作業の前提について」で、衝撃的な次の一文があります。

PC に Git と Node.js がインストールされている必要があります。

保護者の方も、GitやNode.jsを当たり前のようにインストールしなければいけない時代になりましたね。でも、安心してください。Dockerという便利なツールがありますので、簡単に開発環境を整えることができます。

本記事では、Webベースの統合開発環境であるcode-serverとScratch 3.0 拡張機能の開発と実行に必要なソースコード(scratch-vm/scratch-gui)を詰め合わせたDockerコンテナ(jprad/s3coder)を使って、Windowsパソコン上で、Scratch 3.0 GUIサーバーを起動できるようにします。
後半では、「Scratch 3.0の拡張機能を作ってみよう」を参考にして、拡張機能を追加します。

拡張機能を追加して、Scratch 3.0 GUIでコーディング
image.png

必要なもの

Windows 10 パソコンにDockerをインストールしてください。Dockerのインストール方法は、リンク先や各種記事を参照してください。

セットアップと起動

Dockerイメージ(jprad/s3coder)を元にDockerコンテナを起動し、Scratch 3.0 GUIサーバーをWindowパソコンで実行できるようにします。

1. 共有フォルダの作成とDockerコンテナの初回起動

Windows 10 で、コマンドプロンプトを起動し、次の一連のコマンドを入力します。

コマンドプロンプト.cmd
cd c:\
mkdir scratch-ws
docker run --name s3coder -d -p 8080:8080 -p 8601:8601 ^
-v C:/scratch-ws:/home/coder/s3/scratch-ws -e PASSWORD=password ^
jprad/s3coder /home/coder/s3

REM docker run ... のコマンドが長いので「^(キャレット)」で改行しています。

C\scratch-wsフォルダは、Dockerコンテナにマウントされる共有フォルダです(/home/coder/s3/scratch-ws)。
docker runコマンドを開始すると、必要なDockerイメージ(合計:844.17 MB)のダウンロードが始まり、Dockerコンテナが起動されます(コンテナ名:s3coder)。

ダウンロード中のコマンドプロンプト
image.png

ダウンロード完了後、コンテナ起動済みのコマンドプロンプト
image.png

Dockerコンテナの初回起動時に、共有フォルダへのアクセスを許可するかどうかの確認通知が表示されますので、[Share it]で許可します。

共有を許可(Share it
image.png

2.code-severへのログインとScratch 3.0 GUIの起動

Dockerコンテナの起動完了後、code-server ( http://localhost:8080 ) へアクセスし、ログインします(パスワードは、passwordです)。統合開発環境が開きますので、Dockerイメージに同梱されている scratch-guiを起動します。起動方法が構成ファイル(./s3/.vscode/launch.json)に設定されていますので、クリック操作のみで起動できます。scratch-guiの起動完了後、Scratch 3.0 GUI ( http://localhost:8601 ) へアクセスすると、公式ページとは少しばかり異なっていますが、使い慣れたScratch 3.0でのコーディングが行えます。

手順
1. code-server ( http://localhost:8080 ) へアクセスする。
2. パスワードにpasswordと入力し、[SUBMIT]ボタンをクリックし、ログインする。
3. [Run (Ctrl + Shift + D)]アイコンをクリックする。
4. ドロップダウンリストで'Run Scratch 3.0 GUI'(既定)を選択する。
5. [Start Debuging]アイコンをクリックする。
6. [TERMINAL]タブをクリックし、ビルド完了後の'Compiled successfully' が表示されるのを待つ。
7. Scratch 3.0 GUI ( http://localhost:8601 ) へアクセスする。

scratch-guiの起動
image.png

Scratch 3.0 GUI
image.png

3.停止・再開

scratch-guiの再開・停止
scratch-guiを停止せずに再開するには、coder-serverの[Restart (Ctrl+Shift+F5)]アイコンをクリックします。
scratch-guiを停止するには、code-serverの[Stop (Shift+F5)]アイコンをクリックします。

scratch-guiの開始

  1. [Run (Ctrl + Shift + D)]アイコンをクリックする。
  2. ドロップダウンリストで'Run Scratch 3.0 GUI'(既定)を選択する。
  3. [Start Debuging]アイコンをクリックする。
  4. [TERMINAL]タブをクリックし、ビルド完了後の'Compiled successfully' が表示されるのを待つ。

Dockerコンテナの停止
コマンドプロンプトで次のコマンドを実行するとDockerコンテナ(コンテナ名:s3coder)が停止します。

コマンドプロンプト.cmd
docker stop s3coder

Dockerコンテナの再開
コマンドプロンプトで次のコマンドを実行するとDockerコンテナ(コンテナ名:s3coder)が再開します。

コマンドプロンプト.cmd
docker start s3coder

拡張機能の開発

Scratch 3.0 Extensions の開発に関する情報には、次のようなものがあります。

ここでは、「Scratch 3.0の拡張機能を作ってみよう」を参考にログを出力する拡張機能(ブロック)を実装(コピペ)してみます。

拡張機能に必要なファイル

拡張機能(s3coder_newblocks)を実装するには、次のファイルを追加・編集します。

scratch-vm

# フォルダ ファイル 追加 編集 説明
1 scratch-vm/src/extensions/s3coder_newblocks index.js 拡張機能(newblocks)の本体です。
2 scratch-vm/src/extension-support extension-manager.js 追加した拡張機能(s3coder_newblocks)をbuiltinExtensionsに追加登録します。

scratch-gui

# フォルダ ファイル 追加 編集 説明
1 scratch-gui/src/lib/libraries/extensions/s3coder_newblocks newblocks.png 600x372ピクセルのPNG形式ファイルです。拡張機能の選択時にバナーとして表示されます。
2 scratch-gui/src/lib/libraries/extensions/s3coder_newblocks newblocks-small.png 80x80ピクセルのPNG形式ファイルです。ブロックのアイコンとして表示されます。
3 scratch-gui/src/lib/libraries/extensions index.js PNG形式ファイルの読込定義と拡張ブロックの定義を設定します。

scratch-vm での実装

scratch-vmで、拡張機能そのものを実装します。

フォルダ作成

拡張機能用のフォルダを次の手順で作成します。

  1. code-serverのEXPLORERで、s3/scratch-vm/src/extensionsフォルダを選択します。
  2. 右クリックで、コンテキストメニューからNew Folderを選択し、's3coder_newblocks'フォルダを作成します。

index.jsファイルの実装

次の手順で、index.jsファイルを実装します。

  1. 作成した's3coder_newblocks'フォルダで右クリックし、New Fileを選択し、ファイル名をindex.jsとします。
  2. 「Scratch 3.0の拡張機能を作ってみよう/基本の書式 - 拡張機能の追加」からindex.jsのソースコードをコピー&ペーストします。

index.js
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');

/**
 * Icon svg to be displayed at the left edge of each extension block, encoded as a data URI.
 * @type {string}
 */
// eslint-disable-next-line max-len
const blockIconURI = 'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgdmlld0JveD0iMCAwIDQwIDQwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48ZyBpZD0iSUQwLjA4NjgyNDQzOTAwMDMzODMyIiB0cmFuc2Zvcm09Im1hdHJpeCgwLjQ5MTU0NjY2MDY2MTY5NzQsIDAsIDAsIDAuNDkxNTQ2NjYwNjYxNjk3NCwgLTY0LjUsIC03Ny4yNSkiPjxwYXRoIGlkPSJJRDAuNTcyMTQ2MjMwMzc3MjU2OSIgZmlsbD0iI0ZGOTQwMCIgc3Ryb2tlPSJub25lIiBkPSJNIDE4OCAxNDEgTCAyNTAgMTQxIEwgMjUwIDIwMyBMIDE4OCAyMDMgTCAxODggMTQxIFogIiB0cmFuc2Zvcm09Im1hdHJpeCgxLjI4NzkwMzMwODg2ODQwODIsIDAsIDAsIDEuMjg3OTAzMzA4ODY4NDA4MiwgLTExMC45LCAtMjQuNCkiLz48cGF0aCBpZD0iSUQwLjYzODMzNjEzNTA3NDQ5NjMiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIGQ9Ik0gMTk2IDIwNCBDIDE5NiAyMDQgMTkyLjcwNiAxOTAuMDU4IDE5MyAxODMgQyAxOTMuMDc0IDE4MS4yMzYgMTk1Ljg4NiAxNzguNDU4IDE5NyAxODAgQyAyMDEuNDU1IDE4Ni4xNjggMjAzLjQ0MyAyMDMuNzU0IDIwNiAyMDEgQyAyMDkuMjExIDE5Ny41NDIgMjEwIDE2NiAyMTAgMTY2ICIgdHJhbnNmb3JtPSJtYXRyaXgoMSwgMCwgMCwgMSwgLTU3LCAxNS44KSIvPjxwYXRoIGlkPSJJRDAuNzU4NzMwMzU2NTgxNTA5MSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRkZGRkZGIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgZD0iTSAyMTUgMTY5IEMgMjE1IDE2OSAyMTguMzY3IDE2OS41MzQgMjIwIDE3MCBDIDIyMC43MTYgMTcwLjIwNSAyMjEuMjc4IDE3MC44MTkgMjIyIDE3MSBDIDIyMi42NDYgMTcxLjE2MiAyMjMuMzY4IDE3MC43ODkgMjI0IDE3MSBDIDIyNC40NDcgMTcxLjE0OSAyMjUgMTcyIDIyNSAxNzIgIiB0cmFuc2Zvcm09Im1hdHJpeCgxLCAwLCAwLCAxLCAtNTcsIDE1LjgpIi8+PHBhdGggaWQ9IklEMC4yNDM2NzMwNzMxMjc4NjU4IiBmaWxsPSJub25lIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBkPSJNIDIyNyAxNTQgQyAyMjcgMTU0IDIxOC41NTUgMTQ3Ljg5MCAyMTcgMTUxIEMgMjEyLjM0NSAxNjAuMzEwIDIxMS4yODkgMTcxLjczMyAyMTMgMTgyIEMgMjEzLjYxMiAxODUuNjcyIDIyMyAxODcgMjIzIDE4NyAiIHRyYW5zZm9ybT0ibWF0cml4KDEsIDAsIDAsIDEsIC01NywgMTUuOCkiLz48cGF0aCBpZD0iSUQwLjc5MzkzOTQ4MTk1NTAyMTYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIGQ9Ik0gMTc1IDIwMC41MDAgQyAxNzUgMjAwLjUwMCAxNjkuODA1IDIyMS45MTMgMTcxIDIyMi43NTAgQyAxNzIuMTk1IDIyMy41ODcgMTc4Ljc5NSAyMDUuMjk1IDE4Mi41MDAgMjA1Ljc1MCBDIDE4NS45MjAgMjA2LjE3MCAxODEuODU5IDIyNC41MDAgMTg1LjI1MCAyMjQuNTAwIEMgMTg5LjIxMyAyMjQuNTAwIDE5Ny4yNTAgMjA1Ljc1MCAxOTcuMjUwIDIwNS43NTAgIi8+PC9nPjwvc3ZnPg==';

/**
 * Icon svg to be displayed in the category menu, encoded as a data URI.
 * @type {string}
 */
// eslint-disable-next-line max-len
const menuIconURI = 'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgdmlld0JveD0iMCAwIDQwIDQwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48ZyBpZD0iSUQwLjA4NjgyNDQzOTAwMDMzODMyIiB0cmFuc2Zvcm09Im1hdHJpeCgwLjQ5MTU0NjY2MDY2MTY5NzQsIDAsIDAsIDAuNDkxNTQ2NjYwNjYxNjk3NCwgLTY0LjUsIC03Ny4yNSkiPjxwYXRoIGlkPSJJRDAuNTcyMTQ2MjMwMzc3MjU2OSIgZmlsbD0iI0ZGOTQwMCIgc3Ryb2tlPSJub25lIiBkPSJNIDE4OCAxNDEgTCAyNTAgMTQxIEwgMjUwIDIwMyBMIDE4OCAyMDMgTCAxODggMTQxIFogIiB0cmFuc2Zvcm09Im1hdHJpeCgxLjI4NzkwMzMwODg2ODQwODIsIDAsIDAsIDEuMjg3OTAzMzA4ODY4NDA4MiwgLTExMC45LCAtMjQuNCkiLz48cGF0aCBpZD0iSUQwLjYzODMzNjEzNTA3NDQ5NjMiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIGQ9Ik0gMTk2IDIwNCBDIDE5NiAyMDQgMTkyLjcwNiAxOTAuMDU4IDE5MyAxODMgQyAxOTMuMDc0IDE4MS4yMzYgMTk1Ljg4NiAxNzguNDU4IDE5NyAxODAgQyAyMDEuNDU1IDE4Ni4xNjggMjAzLjQ0MyAyMDMuNzU0IDIwNiAyMDEgQyAyMDkuMjExIDE5Ny41NDIgMjEwIDE2NiAyMTAgMTY2ICIgdHJhbnNmb3JtPSJtYXRyaXgoMSwgMCwgMCwgMSwgLTU3LCAxNS44KSIvPjxwYXRoIGlkPSJJRDAuNzU4NzMwMzU2NTgxNTA5MSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRkZGRkZGIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgZD0iTSAyMTUgMTY5IEMgMjE1IDE2OSAyMTguMzY3IDE2OS41MzQgMjIwIDE3MCBDIDIyMC43MTYgMTcwLjIwNSAyMjEuMjc4IDE3MC44MTkgMjIyIDE3MSBDIDIyMi42NDYgMTcxLjE2MiAyMjMuMzY4IDE3MC43ODkgMjI0IDE3MSBDIDIyNC40NDcgMTcxLjE0OSAyMjUgMTcyIDIyNSAxNzIgIiB0cmFuc2Zvcm09Im1hdHJpeCgxLCAwLCAwLCAxLCAtNTcsIDE1LjgpIi8+PHBhdGggaWQ9IklEMC4yNDM2NzMwNzMxMjc4NjU4IiBmaWxsPSJub25lIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBkPSJNIDIyNyAxNTQgQyAyMjcgMTU0IDIxOC41NTUgMTQ3Ljg5MCAyMTcgMTUxIEMgMjEyLjM0NSAxNjAuMzEwIDIxMS4yODkgMTcxLjczMyAyMTMgMTgyIEMgMjEzLjYxMiAxODUuNjcyIDIyMyAxODcgMjIzIDE4NyAiIHRyYW5zZm9ybT0ibWF0cml4KDEsIDAsIDAsIDEsIC01NywgMTUuOCkiLz48cGF0aCBpZD0iSUQwLjc5MzkzOTQ4MTk1NTAyMTYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIGQ9Ik0gMTc1IDIwMC41MDAgQyAxNzUgMjAwLjUwMCAxNjkuODA1IDIyMS45MTMgMTcxIDIyMi43NTAgQyAxNzIuMTk1IDIyMy41ODcgMTc4Ljc5NSAyMDUuMjk1IDE4Mi41MDAgMjA1Ljc1MCBDIDE4NS45MjAgMjA2LjE3MCAxODEuODU5IDIyNC41MDAgMTg1LjI1MCAyMjQuNTAwIEMgMTg5LjIxMyAyMjQuNTAwIDE5Ny4yNTAgMjA1Ljc1MCAxOTcuMjUwIDIwNS43NTAgIi8+PC9nPjwvc3ZnPg==';


/**
 * Class for the new blocks in Scratch 3.0
 * @param {Runtime} runtime - the runtime instantiating this block package.
 * @constructor
 */
class Scratch3NewBlocks {
    constructor (runtime) {
        /**
         * The runtime instantiating this block package.
         * @type {Runtime}
         */
        this.runtime = runtime;

        //this._onTargetCreated = this._onTargetCreated.bind(this);
        //this.runtime.on('targetWasCreated', this._onTargetCreated);
    }


    /**
     * @returns {object} metadata for this extension and its blocks.
     */
    getInfo () {
        return {
            id: 'newblocks',
            name: 'New Blocks',
            menuIconURI: menuIconURI,
            blockIconURI: blockIconURI,
            blocks: [
                {
                    opcode: 'writeLog',
                    blockType: BlockType.COMMAND,
                    text: 'log [TEXT]',
                    arguments: {
                        TEXT: {
                            type: ArgumentType.STRING,
                            defaultValue: "hello"
                        }
                    }
                },
                {
                    opcode: 'getBrowser',
                    text: 'browser',
                    blockType: BlockType.REPORTER
                }
            ],
            menus: {
            }
        };
    }

    /**
     * Write log.
     * @param {object} args - the block arguments.
     * @property {number} TEXT - the text.
     */
    writeLog (args) {
        const text = Cast.toString(args.TEXT);
        log.log(text);
    }

    /**
     * Get the browser.
     * @return {number} - the user agent.
     */
    getBrowser () {
        return navigator.userAgent;
    }
}

module.exports = Scratch3NewBlocks;

image.png

extension-manager.jsファイルの変更

scratch-vm/src/extension-supportフォルダのextension-manager.jsファイルを開き、builtinExtensionsに、次のように拡張機能(s3coder_newblocks)を追加登録します。
※カンマで区切ることを忘れないでください。

extension-manager.js
const builtinExtensions = {
    ...
    gdxfor: () => require('../extensions/scratch3_gdx_for'),
    newblocks: () => require('../extensions/s3coder_newblocks'),
};

image.png

scratch-gui での設定

scratch-guiで、拡張機能を選択できるように設定します。

フォルダ作成

画像保存用のフォルダを次の手順で作成します。

  1. code-serverのEXPLORERで、s3/scratch-gui/src/lib/libraries/extensionsフォルダを選択します。
  2. 右クリックで、コンテキストメニューからNew Folderを選択し、's3coder_newblocks'フォルダを作成します。

画像ファイル

画像ファイルをダウンロードし、作成したフォルダへ保存します。

2つの画像ファイル(クリックして展開)

newblocks.png
image.png

newblocks-small.png
image.png

  1. 2つの画像ファイルをダウンロードし、C:\scratch-wsフォルダへ保存します。
  2. code-serverのEXPLORERで、s3/scratch-wsフォルダを開き、2つの画像ファイルを選択し、右クリックでコンテキストメニューからCopyします。
  3. s3/scratch-gui/src/lib/libraries/extensions/s3coder_newblocksフォルダを選択し、右クリックでコンテキストメニューからPasteします。

image.png

index.jsファイルの設定

s3/scratch-gui/src/lib/libraries/extensionsフォルダのindex.jsファイルを開き、次のように拡張機能の設定を行います。これにより、Scratch 3.0 GUIの拡張機能の追加で、拡張機能を選択できるようになります。

index.js
...
import gdxforConnectionSmallIconURL from './gdxfor/gdxfor-small.svg';

import newblocksImage from './s3coder_newblocks/newblocks.png';
import newblocksInsetImage from './s3coder_newblocks/newblocks-small.png';

export default [
...
        ),
        helpLink: 'https://scratch.mit.edu/vernier'
    },
    {
        name: (
            <FormattedMessage
                defaultMessage="New Blocks"
                description="Name for the 'New Blocks' extension"
                id="gui.extension.newblocks.name"
            />
        ),
        extensionId: 'newblocks',
        iconURL: newblocksImage,
        insetIconURL: newblocksInsetImage,
        description: (
            <FormattedMessage
                defaultMessage="New extension"
                description="Description for the 'New Blocks' extension"
                id="gui.extension.newblocks.description"
            />
        ),
        featured: true
    },
];

image.png

動作確認

scratch-guiを開始し、Scratch 3.0 GUIを開きなおすと、「拡張機能を追加」で、新しい拡張機能を選択できます。
image.png

logブロックを実行すると、ブラウザのConsoleにhelloと出力されます。

image.png

おわりに

2020.11.03 追記
親子でできる!Scratch と AWS を使った “ものづくり” 体験 - 2. 簡単なクイズを作って if-else を学ぶ!編
https://aws.amazon.com/jp/builders-flash/202011/programming-with-kids-2/

【メモ】Dockerイメージの作成
dos.cmd
cd c:\
mkdir scratch-ws
docker run -it -p 8080:8080 -p 8601:8601 -v C:/scratch-ws:/home/coder/s3/scratch-ws -e PASSWORD=password codercom/code-server /home/coder/s3

http://localhost:8080/ へアクセス

sudo apt-get update -y
sudo apt-get install -y nodejs npm
sudo npm install -g npm
sudo chown -R coder:coder /home/coder/s3
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
npm ci
sudo npm link

cd ../scratch-gui
npm ci
sudo npm link scratch-vm

npm start
--->> [Ctrl]+[C]で中断

http://localhost:8601/ へアクセス

  • scratch-guiのポート
    ENV環境変数で設定可能

Dockerfile の記述

docker build -t test-image .

docker run --name test-container -it -p 8080:8080 -p 8601:8601 -v C:/scratch-ws:/home/coder/s3/scratch-ws -e PASSWORD=password test-image /home/coder/s3

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2