Scratch 3.0 を Hackしよう。  scratch-vm.js を使って、100行でHTML5化しよう

Scratch 3.0 自分専用機を作ろうということで、

VM について、解説して行きたいと思います。

まずは、手始めに
今回は、Scratch 2.0 のコードを、Scratch3.0 で動作させてみます。



# Scratch3.0 VM 上で動作させてみよう
今回は、webpack を利用する方法で、実験してみます。



コードは以下

https://github.com/kyorohiro/doc.advent.scratch30/tree/master/scratch-vm-test




[Renderの実験](https://qiita.com/kyorohiro/items/71b5a0c366b1e62600f7) や [Babelの実験](https://qiita.com/kyorohiro/items/58f53fceb021057e1595) や[Webpackの実験](https://qiita.com/kyorohiro/items/2eef7b0de3b5d6e36255) で、環境構築について、

重複するので、端折ります。



## Projectを作る

```
mkdir scratch-vm-test
cd scratch-vm-test/
npm init -f
npm install --save-dev webpack babel-core babel-loader babel-eslint babel-preset-es2015
npm install --save-dev webpack web-dev-server copy-webpack-plugin
npm install --save-dev scratch-vm scratch-storage scratch-render scratch-audio
```



## Webpackの準備をする
以下のような感じ

https://github.com/kyorohiro/doc.advent.scratch30/blob/master/scratch-vm-test/webpack.config.js





## Contentsを追加する
emacs src/index.html

```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Scratch WebGL rendering demo</title>
    <style>
        #scratch-stage { width: 480px; border:3px dashed black;}
    </style>
</head>
<body style="background: lightsteelblue">
<canvas id="scratch-stage"></canvas>
<br>
<button id="start-button">Start</button>
<button id="stop-button">Stop</button>
<script src="scratch-vm-hello.js"></script>
</body>
</html>
```


emacs src/scratch-vm-hello.js

```
const ScratchVM = require("scratch-vm");
const ScratchRender = require("scratch-render");
const ScratchStorage = require("scratch-storage");
const ScratchAudio = require("scratch-audio");

const canvas = document.getElementById('scratch-stage');
const startButton = document.getElementById('start-button');
const stopButton = document.getElementById('stop-button');

const vm = new ScratchVM();
const renderer = new ScratchRender(canvas);
const storage = new ScratchStorage();
const audioEngine = new ScratchAudio();


//
// Assets Setting
//

const ASSET_SERVER = 'https://cdn.assets.scratch.mit.edu/';
const PROJECT_SERVER = 'https://cdn.projects.scratch.mit.edu/';
const getProjectUrl = function (asset) {
    const assetIdParts = asset.assetId.split('.');
    const assetUrlParts = [PROJECT_SERVER, 'internalapi/project/', assetIdParts[0], '/get/'];
    if (assetIdParts[1]) {
        assetUrlParts.push(assetIdParts[1]);
    }
    return assetUrlParts.join('');
};

const getAssetUrl = function (asset) {
    const assetUrlParts = [
        ASSET_SERVER,
        'internalapi/asset/',
        asset.assetId,
        '.',
        asset.dataFormat,
        '/get/'
    ];
    return assetUrlParts.join('');
};

storage.addWebSource([storage.AssetType.Project], getProjectUrl);

storage.addWebSource([storage.AssetType.ImageVector, storage.AssetType.ImageBitmap, storage.AssetType.Sound], getAssetUrl);

vm.attachStorage(storage);


//
// Render Setting
//
vm.attachRenderer(renderer);

//
// Audio Setting
//
vm.attachAudioEngine(audioEngine);

//
// START & Download
//
vm.start();
vm.downloadProjectId("119615668");

//
// Button Action Setting
//
startButton.onclick = function() {
 vm.greenFlag();
};

stopButton.onclick = function() {
 vm.stopAll();
};

```

##  動かしてみる
> webpack-dev-server

Project is running at http://0.0.0.0:8362/

webpack output is served from /



![スクリーンショット 2017-12-23 15.24.25.png](https://qiita-image-store.s3.amazonaws.com/0/54192/f4dbb86c-63f7-7488-db6b-c8de3d26a6d5.png)


動きましたね!!






# PS


### 以下の場所でも、アレコレ書いていきます。


#### Scratch2.0 入門

[火の型 With Scratch 2.0 (プログラム入門) 　第00巻](https://www.gitbook.com/book/kyorohiro/firestyle/details)

<img src="https://qiita-image-store.s3.amazonaws.com/0/54192/ce995d78-4d14-fe94-0ac5-216d24ddf391.png" width=50%>

[火の型 With Scratch 2.0 (プログラム入門) 　第01巻](https://www.gitbook.com/book/kyorohiro/firestyle01/details)
[炎の型 With Scratch 2.0 (ゲームプログラム入門)](https://www.gitbook.com/book/kyorohiro/doc_scratch/details)



#### Scratch3.0 自分専用機 を作ろう!!
[(0)Scratch 3.0 自分専用機 を作ろう!! (0)](http://blogger.firefirestyle.net/2017/09/scratch30-0.html)
[(1) Scratch3.0をビルドしてみよう](
http://blogger.firefirestyle.net/2017/12/scratch30-1-scratch30.html)
[(2) Scratch3.0 を Androidアプリとして動作させてみよう (1)](http://blogger.firefirestyle.net/2017/12/scratch30-2-scratch30-android-1.html)
[(3) Scratch3.0 を Androidアプリとして動作させてみよう (2)](http://blogger.firefirestyle.net/2017/12/scratch-30-3-scratch30-android-2.html)
[(4) Scratch3.0 を Androidアプリとして動作させてみよう (3)](http://blogger.firefirestyle.net/2017/12/scratch-30-3-scratch30-android-3.html)
[(5) Webpack とは)](http://blogger.firefirestyle.net/2017/12/scratch-30-5-webpack.html)
[(6) Scratch3.0 の package.jsonを読んでみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-6-scratch30-packagejson.html)
[(7) scratch-gui を インストールしてみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-7-scratch-gui.html)
[(8) scratch-vm に利用されている、scratch-xxx を触ってみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-8-scratch-vm-scratch-xxx.html)
[(9) Babel を触ってみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-9-babel.html)
[ (10) scratch-render.js で 何か作って触ってみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-9-scratch-renderjs.html)
[ (11) scratch-storage.js を触ってみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-11-scratch-storagejs.html)
[ (12) Blockly を触ってみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-12-blockly.html)
[ (13) Scratch Block に触ってみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-13-scratch-block.html)
[ (14) scratch-vm.js を使って、100行でHTML5化しよう](http://blogger.firefirestyle.net/2017/12/scratch-30-14-scratch-vmjs-100html5.html)