![見出し画像](https://assets.st-note.com/production/uploads/images/74828245/rectangle_large_type_2_0eb5d16b31f531cdc3cd877f01e7f3f1.jpeg?width=1200)
【GASでサイエンス】2D物理シミュレーション用ライブラリ「Matter.js」をGASに組み込んでみる(最終)~準備が済んだらrun!|コードの実装~
この記事は、2次元の物理シミュレーション用ライブラリ「Matter.js」を組み込んだ、GASによる物理シミュレーションアプリのご紹介です。
このアプリは以下の様なデモを実行します。
![](https://assets.st-note.com/production/uploads/images/74828494/picture_pc_54c0f07ffa7da22aa2c63a02d3d0874e.gif?width=1200)
上記の物体の大きさなどの諸元は、以下の様に、Goolgeスプレッドシートにデータを書いて制御できます。
![](https://assets.st-note.com/img/1647960130366-Kbb7YTY1Z1.png)
この記事は、以下の記事の続きとなります。
先回の記事までで、「物理エンジン」「結果の描画」「登場する物体」「空間」の実体化が済み、事前準備が終わりました。
本記事では実装コードを最後にご紹介しています。様々な理由により、この説明通りにいかない場合がしばしばあります。申し訳ありませんが、自己責任・自己解決でお進めくださるよう、お願いいたします。
なお、Matte.jsのコードは以下のサイトを参考にさせて頂きました。この場を借りて御礼申し上げます。
準備が終わったらあとは実行するだけ~物理エンジンと結果描画をrunする~
事前準備が終わり、実行させるのは簡単です。物理エンジンを実行させ、その結果を描画するだけです。
これらのコードは以下の構文になります。
インスタンス.run(実行対象)
コードは以下の様になります。
Engine.run(myEngine);
Render.run(myRender);
上記のコードを実行させると、1、2秒の準備時間を経て、以下の画面が現れます。
![](https://assets.st-note.com/img/1647960702935-cQatH83rgE.png)
その後は、物理法則に従って、長方形とボールが動きます。
![](https://assets.st-note.com/production/uploads/images/74829264/picture_pc_85a65509619bf2d444aa35168700cd4b.gif?width=1200)
このシミュレーションは、単純そうで、意外と複雑な内容をシミュレートしています。
重力による加速
物体同士の衝突
物体の跳ね返りや転がり
摩擦による運動の停止
一連の過程をアニメーション表示する
ユーザーは最初にどういう状態であったかだけ記述すれば良く、あとはライブラリが表示まで含めて処理してくれるのが、「Matte.js」の素晴らしいところです!
このライブラリの主な目的は、ゲームなどに応用して「それらしく」動くアニメーション表示を行う事だと理解していますので、私見ですが、厳密なシミュレーションからは外れている可能性はあると思います(調べられていません)
WEBアプリに使うGoolgeスプレッドシートとGASのコードのご紹介
本アプリのための、スプレッドシート、スクリプトとテンプレートをご紹介します。
スプレッドシート
Googleドライブ上にスプレッドシートを新規作成し、以下のエクセルワークブックを「ファイル」→「インポート」メニューによりアップロードしてインポートしてください。(シート名は変えないでください)
上記の「諸元」シートには、この記事で紹介している例をテスト用に記載しています。
デモだけのアプリですので、ユーザーが編集できるのは黄色いセル(ダウンロード頂くものには色をつけています)の数字だけで、長方形やボールの順序などは変えられません。
インポートしたらGoogleスプレッドシートを表示させた状態で、ブラウザのURLを確認し、スプレッドシートのIDを控えておきましょう。
HTTPS://docs.google.com/spreadsheets/d/★スプレッドシートの
ID★/edit・・・
スクリプトとテンプレート
Googleドライブ上で「新規」→「その他」→「Google Apps Script」を選択し新規のプロジェクトを追加します。作成したらプロジェクトのエディタを開きます。
![](https://assets.st-note.com/img/1647962245619-6B3C7EWw14.png)
コードを以下に記載しますが、手順そのものは以下の記事を参考にしてください。
スクリプトのコード
以下のコードをスクリプトに貼り付けてください。(★スプレッドシートID★の書き換えを忘れずに)
//-----------------------------------------
//----物理エンジン matter.jsの利用------------------
//---著作:Particlemethod-2022年02月01日-----
//---使用は自由ですが著作権は作成者に帰属します---
//-----------------------------------------
//=====doGet関数はURLから呼び出された時に実行する関数|1つだけ定義できます=====
function doGet(e) {
//HTMLファイルのテンプレートをファイル名を指定して取得
var myHTML = HtmlService.createTemplateFromFile('INDEX');
//HTMLファイルをホスティング|メタタグを指定してスマホ表示に対応
return myHTML.evaluate().addMetaTag("viewport", "width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=10.0");
}
//=====HTMLから呼び出されて実行する関数=====
//HTMLテーブルの値myCellsをシートに書き込む関数
function GetSheet(Row0, Col0, nRow, nCol){
//アプリケーションを取得|★スプレッドシートID★は各自のものを記入
var myApp = SpreadsheetApp.openById('★スプレッドシートID★');
//対象シートをシートの名前を指定して取得
var mySheet = myApp.getSheetByName('諸元');
//セル範囲の値を返す
return mySheet.getRange(Row0, Col0, nRow, nCol).getValues();
}
テンプレートのコード
プロジェクトに、テンプレートを追加し、以下のコードを貼り付けます。名前は「INDEX.hrml」とします。
<!--
-----------------------------------------
----物理エンジン matter.jsの利用---------
---著作:Particlemethod-2022年02月01日-----
---使用は自由ですが著作権は作成者に帰属します---
-------------------------------------------
--------------参考サイト--------------
https://yujin777.com/2020/08/21/matter-js-sample-12-%E8%90%BD%E4%B8%8B%E3%81%99%E3%82%8B%E9%95%B7%E6%96%B9%E5%BD%A2%E3%81%A8%E5%86%86/
-->
<html>
<head>
<meta charset="UTF-8" />
<!--ライブラリ「Matte.js」の組み込み--->
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.14.2/matter.min.js"></script>
</head>
<body>
<script>
//====Matter.jsの道具立て(インスタンス)を用意=====
//物理エンジンのインスタンス
var Engine = Matter.Engine;
//レンダリング(描画機能)のインスタンス
var Render = Matter.Render;
//シミュレーションする舞台(ワールド)のインスタンス
var World = Matter.World;
//登場させる物体のインスタンス
var Bodies = Matter.Bodies;
//====インスタンスを実体化=====
//使用する物理エンジンの宣言
var myEngine = Engine.create();
//使用する画面(レンダリング)の宣言
var myRender = Render.create({
//画面(CANVAS要素)をどこに置くか
element: document.body,
//使用する物理エンジン
engine: myEngine,
//画面サイズ、簡易表示(ワイヤフレーム)有無
options: {
width: 650,
height: 350,
wireframes: false,
},
});
//==テーブルのセルの値をGASのSetSheet 関数に渡し、成功したらonSuccessを実行==
//★★セルのデータを増やした場合は、GetSheet(データ開始行,データ開始列, データ行数, データ列数)を編集★★
google.script.run.withSuccessHandler(onSuccess).GetSheet(3, 2, 5, 4);
//script.run関数が成功したら、セルの内容を記憶したres配列を使って以下を実行
function onSuccess(res){
//長方形 rectangle(x座標,y座標,幅,高さ)
var myBoxA = Bodies.rectangle(res[0][0], res[0][1], res[0][2], res[0][3]);
//長方形 | isStatic: true ← 不動設定
var myBoxB = Bodies.rectangle(res[1][0], res[1][1], res[1][2], res[1][3], { isStatic: true });
//ボール circle(x座標,y座標,半径)
var myBallA = Bodies.circle(res[2][0], res[2][1], res[2][2]);
var myBallB = Bodies.circle(res[3][0], res[3][1], res[3][2]);
//地面:長方形&不動設定
var myGround = Bodies.rectangle(res[4][0], res[4][1], res[4][2], res[4][3], { isStatic: true });
//空間の実体化|空間を支配する物理エンジン、物体を記載します
World.add(myEngine.world, [myBoxA, myBoxB, myBallA, myBallB, myGround]);
//シミュレーションの実行と結果の描画
Engine.run(myEngine);
Render.run(myRender);
}
</script>
</body>
</html>
以上となります。
コードを保存してデプロイしたら、URLにアクセスしてみてください。扉のアニメーションが表示されるはずです。
この説明通りにいかない場合は申し訳ありませんが、自己責任・自己解決でお進めくださるよう、お願いいたします。
![](https://assets.st-note.com/img/1647963413989-1D5mHa8VUw.jpg)
GASでWEBアプリを作る記事を、解説書にしてみました。拙い解説ですが、宜しければどうぞ。
本書の内容は、以下の記事をご覧ください。