第22話
使ってみた

物理演算エンジン「Matter.js」を使ってみた(スマホも対応)


物理演算エンジン「Matter.js」を使ってみた(スマホも対応)

こんにちは、おじいちゃんです。

今回は物理演算エンジンであるMatter.jsをご紹介したいと思います。

Matter.jsとは

pic01

Matter.jsは、物理演算が必要なアニメーションやWebゲームなどを作りたいときに使えるJavaScriptライブラリです。スマートフォンにも対応しているとのこと、ありがたいですね。

下記サイトからダウンロードすることができます。

サイト内のDEMOでは、色々なサンプルがありパラメータも変更できるようになっているので触ってみてください。

ボールを落とす

それでは簡単なサンプルを作ってみましょう。

まずはボールが落ちるサンプルです。

(function () {
    //使用するメソッドを読み込む
    var Engine = Matter.Engine,
        Gui = Matter.Gui,
        World = Matter.World,
        Bodies = Matter.Bodies,
        Body = Matter.Body,
        Composite = Matter.Composite,
        Composites = Matter.Composites,
        Common = Matter.Common,
        Constraint = Matter.Constraint,
        RenderPixi = Matter.RenderPixi,
        Events = Matter.Events,
        Bounds = Matter.Bounds,
        Vector = Matter.Vector,
        Vertices = Matter.Vertices,
        MouseConstraint = Matter.MouseConstraint;

    var STARGE = {};

    var _engine,
        _gui;

    //初期化
    STARGE.init = function () {

        //描画するDOMを取得
        var container = document.getElementById('stage');

        var options = {
            positionIterations: 6,
            velocityIterations: 4,
            enableSleeping: false
        };

        //描画域を作成(描画したいDOM,オプションを読み込む)
        _engine = Engine.create(container, options);

        //実行
        Engine.run(_engine);

        STARGE.ballSample();
    };

    //ページの読み込みが終わったらSTARGE.initを実行
    if (window.addEventListener) {
        window.addEventListener('load', STARGE.init);
    } else if (window.attachEvent) {
        window.attachEvent('load', STARGE.init);
    }

    STARGE.ballSample = function () {
        var _world = _engine.world;

        STARGE.reset();

        //circle(x座標,y座標,大きさ,オプション)
        var ball = Bodies.circle(530, 100, 50, {render: {fillStyle: '#d04030'}
        });

        //World.add(追加)
        World.add(_world, [ball]);
    };
    
    //描画域の設定
    STARGE.reset = function () {

        var _world = _engine.world;

        //描画クリア
        World.clear(_world);
        Engine.clear(_engine);

        //重力値
        _engine.world.gravity.y = 1;

        var offset = 0;

        //矩形で枠線を作る(rectangle(x座標,y座標,横幅,縦幅,option))
        World.add(_world, [
            Bodies.rectangle(400, 0, 800, 1, {isStatic: true}),
            Bodies.rectangle(800, 300, 1, 600, {isStatic: true}),
            Bodies.rectangle(0, 0, 1, 600, {isStatic: true}),
            Bodies.rectangle(400, 600, 800, 1, {isStatic: true})
        ]);
        //renderのオプション(各種renderのオプション)
        var renderOptions = _engine.render.options;
        renderOptions.wireframes = false;
    };
})();

rakka

生成した描画域内でボールが落ちましたね。

このようにオブジェクトを配置するだけで、物理演算を利用したアニメーションを実装することができます。

オプションや機能などはドキュメントにまとめられています。

今回はいくつかわかりやすい機能だけご紹介します。

ボールを固定する

さきほどはボールを生成しただけで落ちていきました。今度はボールを固定してみましょう。

circleのオプションにあるisStaticをtrueをすることで、固定することができます。

        var ball = Bodies.circle(375, 100, 50, {
            //固定するかをtrueかfalseで変更
            isStatic: true,
            render: {
                lineWidth: 1,
                strokeStyle: '#d04030',
                fillStyle: '#d04030'
            }
        });

バウンドさせてみる

circleのオプションにあるrestitutionに任意の値を入れることで、バウンドさせることができます。

        //circle(x座標,y座標,大きさ)
        var ball = Bodies.circle(375, 100, 50, {
            //バウンドさせたい場合はrestitutionに任意の値を渡す
            restitution: 0.9,
            isStatic: false,
            render: {
                lineWidth: 1,
                strokeStyle: '#d04030',
                fillStyle: '#d04030'
            }
        });

bound

簡単にボールをバウンドさせることができましたね。

梃子を作ってみる

次に梃子を作ってみます。

必要な図形を生成して、各オブジェクトの比重(density)を指定します。

    STARGE.ballSample = function () {
        var _world = _engine.world;

        STARGE.reset();

        var ball = Bodies.circle(530, 100, 50, {
       density: 5,
            render: {
                fillStyle: '#d04030'
            }
        });
       
        //
        var catapult = Bodies.rectangle(400, 520, 330, 20, {
            density: 1,
            render: {
                fillStyle: '#efb233'
            }
        });

        var fodder = Bodies.rectangle(250, 500, 44, 44, {
       density: 0.3,
            render: {
                fillStyle: '#12579f'
            }
        });

 

次に生成した図形を追加してあげて、支点を支えるためのConstraintを生成。

        World.add(_world, [
            ball
            catapult,
            fodder,
            Constraint.create({
                bodyA: catapult,
                pointB: {
                    x: 350,
                    y: 600
                },
                isStatic: true,
                render: {
                    visible: true
                }
            }),
            Constraint.create({
                bodyA: catapult,
                pointB: {
                    x: 450,
                    y: 600
                },
                isStatic: true,
                render: {
                    visible: true
                }
            })
        ]);
    };

 

固定したいオブジェクト(bodyA)と、どのポイントを軸に固定したいかという座標(pointB)を指定したConstraintを作ることで、点を固定することができます。

teco

梃子の動きを作ることができました。

おわりに

物理演算、使い方を考えると夢が広がりますね。

Matter.jsを利用して面白いアニメーションを作ってみてはいかがでしょうか。

週末にバスケをはじめたのですが、筋肉痛で3日ほどリアルおじいちゃんだったおじいちゃんでした。

まんだらっ

 

【まだまだあるぞ、便利なライブラリ】

「RxJS」初心者入門 – JavaScriptの非同期処理の常識を変えるライブラリ

Seriously.jsで動画・画像にリアルタイムエフェクトをかける方法【ほりぼーいドッキリ編】

アニメーションに便利なJavaScriptライブラリTweenMaxを使ってみる(その1)

Web初心者でもGoogle Mapsをカスタマイズできるgmaps.jsでAPIを使い倒そう!

p5.jsでProcessingのようにリッチなWeb表現を作るチュートリアル


この記事を書いた人

おじいちゃん
おじいちゃん フロントエンドエンジニア 2014年入社
フロントエンドエンジニアのおじいちゃんと言います。本当は24歳です。よろしくお願いします。