🪂

matter.jsでつくるタワーバトルゲーム

2023/09/12に公開

ちょってぃタワーバトル

弊社キャラクターの「ちょってぃ」を使ったタワーバトルゲームを作りました。(つみあげるだけです)
https://fukekazki.github.io/chotty-tower-battle/
ちょってぃタワーバトル

matter.jsとは

matter.jsはJavaScriptで扱える2Dの物理演算エンジンです。重力があったり物体の当り判定ができます。公式では多くのデモが紹介されています。

今回はこの物理演算を用いてタワーバトルを実装したときのTipsを紹介します。

実装時のTips

環境

  • Vite v4.4.9
  • matter.js v0.19.0

オブジェクトの生成

オブジェクトは重力によって下に落下します。
床のような固定されているオブジェクトを生成するときはisStaticをつけてあげます。

床を生成する例
const ground = Bodies.rectangle(x, y, width, height, {
  isStatic: true,
});

タワーバトルの実装

タワーバトルの実装は簡単です。canvasをクリックしたタイミングでオブジェクトを生成してあげるだけです。その後の落下や当り判定はmatter.jsに任せます。

render.canvas.addEventListener("touchend", handleTouch);

const handleTouch = () => {
  const chotty = createChotty();
  Composite.add(engine.world, chotty);
};

svg画像から当り判定のあるオブジェクトを生成

matter.jsで生成できる基本オブジェクトはcircle(円),polygon(多角形),rectangle(長方形),trapezoid(台形)です。複雑な形のオブジェクトを生成するときはBodies.fromVertices関数を使います。
Bodies.fromVerticesは頂点データからオブジェクトを生成します。

今回はちょってぃ.svgデータから頂点データの生成がしたいです。
matter.jsではSvg.pathToVertices関数をつかってできます。

以下の関数はViteでimportしたsvg画像から頂点データを生成します。
注意点としてSvg.pathToVerticesを使うときはpathseg.jsが必要になります。

Viteでimportしたsvg画像から頂点データを生成
export const getVerticesFromSvg = async (path: string) => {
  const svgDoc = await fetch(path)
    .then((response) => response.text())
    .then((svgString) => {
      // SVG文字列からpathデータを抽出
      const parser = new DOMParser();
      return parser.parseFromString(svgString, "image/svg+xml");
    });
  const pathDatas = svgDoc.querySelectorAll("path");
  if (!pathDatas) return;
  // pathデータをverticesに変換
  const vertices = Array.from(pathDatas).map((pathData) => {
    return Matter.Svg.pathToVertices(pathData, 10);
  });
  return vertices;
};
ちょってぃを生成する例
import ChottySvg from '@/assets/chotty.svg';
import ChottyPng from '@/assets/chotty.png';
// 頂点データの生成
const vertices = getVerticesFromSvg(ChottySvg);
// オブジェクトの生成
const chotty = Bodies.fromVertices(x, y, vertices, {
  label: "chotty",
  render: {
    sprite: {
      texture: ChottyPng,
    },
  },
});

オブジェクトの数をカウントする

EventsオブジェクトのafterUpdateをつかってmatter.jsの計算後に関数を実行できます。
Composite.allBodies関数でエンジンの世界にあるすべてのオブジェクトを取得できます。
オブジェクトを生成するときにlabelを付与しておくと、ここでlabelを使ったフィルタリングができ、ちょってぃの数をカウントできました。

ちょってぃの数をカウントする例
Events.on(engine, "afterUpdate", function() {
  const bodies = Composite.allBodies(engine.world);
  const chottyCount = bodies.filter((v) => v.label === "chotty").length;
});

まとめ

matter.jsを使うと簡単に物理演算のある2Dゲームをつくれます。
是非挑戦してみてください🐱。

GitHubで編集を提案
chot Inc. tech blog

Discussion