如何在matter.js中移动通过约束连接的物体?

huangapple go评论71阅读模式
英文:

How to move bodies connected with constraint in matter.js?

问题

I have an object that consists of multiple bodies connected with constraints. This is not a compound body in terms of matter.js because, in my case, bodies can rotate independently.

The problem is that when I'm trying to move one of the bodies using setPosition (see demo below), I'm expecting the other linked bodies to move too based on the constraint, but it is not the case. Instead, the matter.js solver makes them rotate arbitrarily as I have applied some force to them. To work around this, I can potentially remove constraints, move bodies, and then re-apply the constraint but it feels too complicated (imagine that I have many bodies and constraints between them) and not elegant.

Question: Is there a way in matter.js to move multiple bodies connected with constraints?

英文:

I have an object that consists of multiple bodies connected with constraints. This is not a compound body in terms of matter.js because, in my case, bodies can rotate independently.

The problem is that when I'm trying to move one of the bodies using setPosition (see demo below), I'm expecting the other linked bodies to move too based on the constraint, but it is not the case. Instead, the matter.js solver makes them rotate arbitrarily as I have applied some force to them. To work around this, I can potentially remove constraints, move bodies, and then re-apply the constraint but it feels too complicated (imagine that I have many bodies and constraints between them) and not elegant.

Question: Is there a way in matter.js to move multiple bodies connected with constraints?

The problem demo:
<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const engine = Matter.Engine.create();
engine.world.gravity.y = 0;

const render = Matter.Render.create({
  element: document.querySelector(&#39;#container&#39;),
  engine: engine,
  options: {
    width: 800,
    height: 600,
    showAngleIndicator: false
  }
});

const bodyA = Matter.Bodies.rectangle(50, 50, 20, 60);
const bodyB = Matter.Bodies.rectangle(80, 30, 60, 20);
const constraintAB = Matter.Constraint.create({
  bodyA,
  bodyB,
  pointA: {
    x: 10,
    y: -20
  },
  pointB: {
    x: -30,
    y: 0
  },
  length: 0,
  stiffness: 0.9,
});

Matter.World.add(engine.world, constraintAB);
Matter.World.add(engine.world, [bodyA, bodyB]);

const runner = Matter.Runner.create();
Matter.Runner.run(runner, engine);
Matter.Render.run(render);

setTimeout(() =&gt; {
  Matter.Body.setPosition(bodyA, { x: 400, y: 200 });
  
  // Moving on small distance works but this is not what I need
  // Matter.Body.translate(bodyA, { x: 2, y: 2 });
}, 2000);

<!-- language: lang-html -->

&lt;html&gt;

&lt;head&gt;
  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.min.js&quot; integrity=&quot;sha512-0z8URjGET6GWnS1xcgiLBZBzoaS8BNlKayfZyQNKz4IRp+s7CKXx0yz7Eco2+TcwoeMBa5KMwmTX7Kus7Fa5Uw==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;
  &lt;style&gt;

  &lt;/style&gt;
&lt;/head&gt;

&lt;body&gt;
  &lt;div id=&#39;container&#39; style=&#39;width: 500px; height: 500px&#39;&gt;&lt;/div&gt;
&lt;/body&gt;

&lt;/html&gt;

<!-- end snippet -->

答案1

得分: 0

我认为没有一种特定于物体的方式来移动多个物体,如果它们不都是一个复合物体的一部分。但在你的情况下,足够将与约束连接的所有物体进行平移,而不仅仅是一个。你还应该为每组这样的物体设置唯一的标签。使用这种方法,您将无需重新应用约束。

setTimeout(() => {
  const allBodies = Composite.allBodies(engine.world).filter(
    (el) => el.label === "my-label"
  );

  allBodies.forEach((el) => {
    Body.translate(el, { x: 200, y: 100 });
  });
}, 2000);
英文:

I think there's no matter-specific way to move multiple bodies, if they are not all parts of a compound body. But in your case, it is enough to translate all bodies connected with constraint, instead of just one. You also should set unique label for each such group of bodies. You won't have to reapply constaints using this approach.

setTimeout(() =&gt; {
  const allBodies = Composite.allBodies(engine.world).filter(
    (el) =&gt; el.label === &quot;my-label&quot;
  );

  allBodies.forEach((el) =&gt; {
    Body.translate(el, { x: 200, y: 100 });
  });
}, 2000);

huangapple
  • 本文由 发表于 2023年6月8日 23:03:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76433217.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定