💙
【Matter.js】SVGの凹面処理による複合ボディに単一のテクスチャを適応する
解決したい問題
poly-decomp.jsというライブラリで複数の凸面のみのパーツに分割し、それらのパーツをまとめて複合ボディとして生成する。
で、複合ボディにテクスチャを適応するとこうなる。
チューチュートレイン
// Matter.jsのワールドに追加
const body = Bodies.fromVertices(
x,
y,
vertices,
{
mass,
render: {
sprite: {
texture: texture(), // テクスチャ画像のパス
xScale: scale, // x方向のスケール
yScale: scale, // y方向のスケール
},
},
},
false
);
// パーツが複数生成されていること、それぞれにテクスチャが反映されていることがわかる
console.log("Generated vertices:", body.parts);
解決法
issueの一覧を見てみると、公式にバグとしてマークされているものの正式な修正は無い模様。
以前からmatter.js関連でお世話になっていたサイトを見てみると、ドンピシャな回答が載っていた。
これを防ぐためにソースコードの修正が必要になる。(matter.jsのRender.bodiesを定義しているところ)
// handle compound parts
for (k = body.parts.length > 1 ? 1 : 0; k < body.parts.length; k++) {
part = body.parts[k];
↓
// handle compound parts
const parts = body.render.sprite.single ? 1 : body.parts.length;
for (k = !body.render.sprite.single && body.parts.length > 1 ? 1 : 0; k < parts; k++) {
part = body.parts[k];
さらに、index.jsのaddIconObject()のオブジェクト生成時のrender.spriteオプションにsingle: trueを追加する。
render: {
sprite: {
texture: originCanvas.toDataURL(),
single: true,
}
},
さっそくライブラリを書き換えて、single
というオプションを生やそう。
npmパッケージ(ライブラリ)にパッチを当てる
patch-packageを使用することにした。
node_modulesフォルダ内のmatter-jsの該当部分を書き換えて、以下を実行するだけ。
npx patch-package matter-js
これでコードの差分を記録したpatch用のフォルダとファイルが生成されて、変更をgitで管理することができる。
以降新しくインストールしたときにも、以下でpatchが適用される。
npx patch-package
singleオプションの適応
// Matter.jsのワールドに追加
const body = Bodies.fromVertices(
x,
y,
vertices,
{
mass,
render: {
sprite: {
texture: texture(), // テクスチャ画像のパス
xScale: scale, // x方向のスケール
yScale: scale, // y方向のスケール
+ single: true, // テクスチャを1つのパーツにのみ適用
},
},
},
false
);
console.log("Generated vertices:", body.parts);
位置のズレなどもなく、いい感じ。
Discussion