matter.jsでつくるタワーバトルゲーム
ちょってぃタワーバトル
弊社キャラクターの「ちょってぃ」を使ったタワーバトルゲームを作りました。(つみあげるだけです)
ちょってぃタワーバトル
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が必要になります。
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ゲームをつくれます。
是非挑戦してみてください🐱。
ちょっと株式会社(chot-inc.com)のエンジニアブログです。 フロントエンドエンジニア募集中! カジュアル面接申し込みはこちらから chot-inc.com/recruit/iuj62owig
Discussion