英文:
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('#container'),
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(() => {
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 -->
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.min.js" integrity="sha512-0z8URjGET6GWnS1xcgiLBZBzoaS8BNlKayfZyQNKz4IRp+s7CKXx0yz7Eco2+TcwoeMBa5KMwmTX7Kus7Fa5Uw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<style>
</style>
</head>
<body>
<div id='container' style='width: 500px; height: 500px'></div>
</body>
</html>
<!-- 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(() => {
const allBodies = Composite.allBodies(engine.world).filter(
(el) => el.label === "my-label"
);
allBodies.forEach((el) => {
Body.translate(el, { x: 200, y: 100 });
});
}, 2000);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论