7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

matter.jsでオブジェクトに引力を付与する

Last updated at Posted at 2024-08-30

はじめに

matter.jsでワールドではなくオブジェクトに引力をつけて惑星みたいな挙動を作りたかった。

だいぶ前にもmatter.jsユーザの中でこの機能を欲する声があったらしいが、公式ライブラリではなく、プラグインで対応することになったらしい。


が、そのプラグインは7年前で更新が止まっており、最新のmatter.jsだと動かない...

幸いなことにコード見てみたら意外と簡単な実装だったので自分で再現してみようと思った。

作りたいもの

下記のデモみたいなやつ

実装

※基本的なMatter.jsの設定は実装できている前提

まず下記のAttractorを準備する。

const setAttractor = (bodyA: Matter.Body, bodyB: Matter.Body) => {
  return {
    x: (bodyA.position.x - bodyB.position.x) * 1e-6,
    y: (bodyA.position.y - bodyB.position.y) * 1e-6,
  };
}

これは二つの物体間に発生する引力のベクトルを戻り値として返す。

次にafterUpdate内で下記のように利用することで引力を付与する仕組みを作ることができる。

Matter.Events.on(engine, 'afterUpdate', (event) => {
    let bodies = Matter.Composite.allBodies(engine.world)

    for (let i = 0; i < bodies.length; i++) {
      const bodyA = bodies[i]
      
      // 引力を付与したい物体の作成時にblackhallBallsという配列にidを追加している
      if (blackhallBalls.includes(bodyA.id)) {
        for (let j = 0; j < bodies.length; j++) {
          const bodyB = bodies[j]
          const force = setAttractor(bodyA, bodyB)

          // ここで引き寄せられる側の物体に引力を適用する
          Matter.Body.applyForce(bodyB, bodyB.position, Matter.Vector.create(force.x, force.y))
        }
      }
    }
  })

実際に動かしてみたデモ

abcde.gif

それっぽい感じになった!

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?