株式会社グローバルゲート公式ブログ
こんにちは、株式会社グローバルゲートのモーリーです。
米不足が解消され、我が家で常食しているゆめぴりかもスーパーに新米が並ぶようになって一安心です。
…が、大幅に値上がりしてしまって5kgで3500円…主食を米ではなく麺にしようかと真剣に考えました…。
さて、今回はJavascriptの物理エンジン「Matter.js」を使って、重力や衝突といった物理現象をWebサイト上で表現してみたいと思います。
物理エンジンとは、コンピュータ内で重力や衝突などの物理法則をシミュレーションし、物体の動きを現実世界に基づいて再現するためのプログラムです。主にゲーム開発、シミュレーション、アニメーション制作などの分野で利用され、重力、摩擦、衝突、反射などの物理現象を再現します。物理エンジンを使うことで、キャラクターが坂を下りるときの加速や、物体が壁に衝突したときの反発などをリアルにシミュレーションすることができます。
主に以下のような機能を持ちます。
剛体シミュレーション: 剛体(硬い物体)の運動や衝突を計算し、どのような動きをするかをシミュレーションします。
流体シミュレーション: 液体や気体の流れをシミュレーションします。
衝突検出: ボールが壁にぶつかったあとの動きなど、物体同士がぶつかった時にどのように反応するかをシミュレーションします。
柔軟体シミュレーション: 布やゴムのような柔らかい物体の変形をシミュレーションします。
今回使ってみるMatter.jsはJavaScriptで記述されたオープンソースの2D物理エンジンで、ウェブブラウザ上で動作するため、HTML5を用いたゲームやインタラクティブなWebアプリケーションで広く利用されています。
物理エンジンは複雑な計算が必要なため扱いが難しいのですが、Matter.jsは比較的シンプルなコードで扱うことができます。
Matter.jsを使うことで簡単に物理法則をWebアプリケーションに簡単に組み込むことができ、2DゲームやWebサイトのアニメーション表現を向上させることができます。
それでは実際にMatter.jsを使ってみましょう。
チュートリアルを参考に簡単な処理を書いてみました。
まずは簡単に箱が上から降ってくるだけのアニメーションを実装してみます。
箱と地面を定義することでそれぞれが描画され、描画が完了すると箱は地面まで落下します。
重力をシミュレートしているため、落下速度が徐々に早くなっている点がポイントです。
地球上の重力加速度は9.8m/s^2ですが(習うのは中学だったか高校だったか思い出せませんが…)、試しに重力を半分にしてみましょう。
Matter.jsでは以下の記述で重力を調整することができます。
engine.world.gravity.y = 0.5;
そうすると落下速度も遅くなりました。
次に物体に反発力を持たせ、落とした物体がバウンドするようにしてみましょう。
物体定義の際にrestitutionというオプションを追加することでその物体は弾性を持ちます。
合わせてdensity(密度)も定義してみます。これは物体の重さを定義するもので、小さい数値にすると密度の高い(つまり重い)物体となります。
var boxA = Bodies.rectangle(300, 0, 80, 80, {
render: {
fillStyle: '#343b81'
},
restitution: 1.5, //弾性を持たせる
density: 0.001,//密度(小さいほど重い)
});
箱に弾性を設定し、上に来る箱の密度を高くしたことで抑え込まれるような動きとなりました。
Matter.jsではクリックやドラッグなどでオブジェクトを操作することができます。
この機能も試してみます。
クリックするとその位置からランダムな色とサイズの球体が生成される処理を作ってみました。
クリックイベントはHTMLのクリックと同じくaddEventListenerで定義します。
document.addEventListener('click', function (event) {
// クリック位置を取得(キャンバス内の座標)
const rect = render.canvas.getBoundingClientRect();
const mouseX = event.clientX - rect.left;
const mouseY = event.clientY - rect.top;
// クリック位置に円のオブジェクトを生成
//生成される円のサイズ範囲を指定
const circleSizeMax = 100;
const circleSizeMin = 10;
const circleSize = Math.floor(Math.random() * (circleSizeMax - circleSizeMin + 1)) + circleSizeMin;
//生成される円の色を指定
const color = '#' + Math.floor(Math.random() * 16777215).toString(16)
const circle = Bodies.circle(mouseX, mouseY, circleSize, {
restitution: 0.5,
render: {
fillStyle: color,
}
});
// 生成したオブジェクトをワールドに追加
World.add(world, circle);
});
最後に簡単なブロック崩しゲームを作ってみました。
ゲームオーバーやクリアの処理は作ってませんので失敗した場合はリロードして遊んでみてください。
これだけでもかなり大変だった…。
実際にゲームとして成立させるためには、ボールが落下したときにゲームオーバーとして判定する、破壊したブロックの個数を得点として計算する、スコアを保存する、など、まだまだ多くの機能を実装する必要があります。
ゲーム制作は難しいですね。
ということで、今回はJavascript製2D物理エンジンのMatter.jsを使って簡単な処理を書いてみました。
以前当ブログでCSSによるイージングについてご紹介しましたが、イージングも簡易的に物理現象をシミュレートしたものと言えます。
Matter.jsを使うことでより複雑でリアリティのある表現ができるかもしれません。どのような表現ができるか、引き続き模索していきたいと思います。
【関連記事】
カテゴリー
月別アーカイブ
ブログ内検索
執筆メンバーについて
モーリー
Webデザイナー。
当サイトのデザインと管理も担当しています。
ナミー
Webディレクター。
本社制作部の紅一点。お客様に寄り添った提案を心かげています。
タカ
サーバーエンジニア。
Webサイトにとってサーバーは命、ネットワークは血液です。Webサイトの安定稼働のために日夜注力しています。
たっくん
ITアドバイザー
Webサイトの活用方法からオフィスのネットワーク整備まで、多角的にITの活用方法をご案内させていただきます。
ノーさん
制作部ディレクター。
業種を問わず多くのお客様を担当させていただきました。Webサイトのお悩み、活用方法などぜひご相談ください。
カン
制作部デザイナー。
制作部最年少の若手ですが、だからこそ生まれるアイデア・発想にご期待ください。
当社サービスについてのお問い合わせは下記までご連絡下さい。
06-6121-7581 / 03-6415-8161