Matter.js 禁用不同复合材料之间的碰撞
Matter.js disable collision between different composites
我正在尝试使用 "Matter.js body documentation" 中描述的碰撞过滤。但是,对于我的项目,我需要禁用不同复合对象之间的碰撞。所以只有在同一个复合体中的物体才会发生碰撞。我计划拥有超过 32 个复合材料(32 是 Matter.js 提供的最大碰撞类别数量)。我将如何实现这一目标?
// module aliases
var Engine = Matter.Engine,
Render = Matter.Render,
World = Matter.World,
Bodies = Matter.Bodies,
Body = Matter.Body,
Vector = Matter.Vector,
Composite = Matter.Composite,
Constraint = Matter.Constraint,
MouseConstraint = Matter.MouseConstraint;
// create an engine
var engine = Engine.create();
// create a renderer
var container = document.getElementById("container");
var canvas = document.getElementById("maincanvas");
var render = Render.create({
element: container,
canvas: canvas,
engine: engine,
options: {
height: 400,
width: 400,
wireframes: false
}
});
// This makes collision much easier to test
engine.world.gravity = {x:0, y:0};
// Add a mouseconstraint to test
var mc = MouseConstraint.create(engine, {
element: render.canvas
});
Composite.add(engine.world, mc);
var bodies1 = []
var bodies2 = []
var xpos = 30
var ypos = 30
for (var i = 0; i < 5; i++){
bodies1.push(Bodies.circle(xpos, ypos, 10, {
collisionFilter: {
group:-1
},
render: {
fillStyle: "blue"
}
})
);
xpos += 30;
}
for (var i = 0; i < 5; i++){
bodies2.push(Bodies.circle(xpos, ypos, 10, {
collisionFilter: {
group:-1
},
render: {
fillStyle: "red"
}
})
);
xpos += 30;
}
var composite1 = Composite.create();
Composite.add(composite1, bodies1);
var composite2 = Composite.create();
Composite.add(composite2, bodies2);
Composite.add(engine.world, [composite1, composite2]);
Engine.run(engine);
Render.run(render);
这样我就可以禁用复合材料之间的碰撞,但这也会禁用碰撞 'inside' 复合材料。我可以用 collisionFilter.category
系统做到这一点,但它如何处理超过 32 个复合材料?
不支持复合级别的碰撞过滤,您需要在主体级别进行处理。为了使其更易于管理,只需创建一些复合辅助函数,例如compositeSetCollisionFilter(composite, filter)
并遍历 Composite.allBodies(composite)
.
关于32个类别的限制,这是由于bitwise implementation (for performance supposedly, though I doubt it matters much in reality). I've raised an issue on the project about reconsidering this。
如果您将 Matter.Detector.canCollide(filterA, filterB) 替换为您自己的可以比较两个 body.collisionFilter
对象的函数,那么现在有一种方法可以获得更多。有了这个,您可以为 body.collisionFilter
个对象使用任何您喜欢的方案。
我正在尝试使用 "Matter.js body documentation" 中描述的碰撞过滤。但是,对于我的项目,我需要禁用不同复合对象之间的碰撞。所以只有在同一个复合体中的物体才会发生碰撞。我计划拥有超过 32 个复合材料(32 是 Matter.js 提供的最大碰撞类别数量)。我将如何实现这一目标?
// module aliases
var Engine = Matter.Engine,
Render = Matter.Render,
World = Matter.World,
Bodies = Matter.Bodies,
Body = Matter.Body,
Vector = Matter.Vector,
Composite = Matter.Composite,
Constraint = Matter.Constraint,
MouseConstraint = Matter.MouseConstraint;
// create an engine
var engine = Engine.create();
// create a renderer
var container = document.getElementById("container");
var canvas = document.getElementById("maincanvas");
var render = Render.create({
element: container,
canvas: canvas,
engine: engine,
options: {
height: 400,
width: 400,
wireframes: false
}
});
// This makes collision much easier to test
engine.world.gravity = {x:0, y:0};
// Add a mouseconstraint to test
var mc = MouseConstraint.create(engine, {
element: render.canvas
});
Composite.add(engine.world, mc);
var bodies1 = []
var bodies2 = []
var xpos = 30
var ypos = 30
for (var i = 0; i < 5; i++){
bodies1.push(Bodies.circle(xpos, ypos, 10, {
collisionFilter: {
group:-1
},
render: {
fillStyle: "blue"
}
})
);
xpos += 30;
}
for (var i = 0; i < 5; i++){
bodies2.push(Bodies.circle(xpos, ypos, 10, {
collisionFilter: {
group:-1
},
render: {
fillStyle: "red"
}
})
);
xpos += 30;
}
var composite1 = Composite.create();
Composite.add(composite1, bodies1);
var composite2 = Composite.create();
Composite.add(composite2, bodies2);
Composite.add(engine.world, [composite1, composite2]);
Engine.run(engine);
Render.run(render);
这样我就可以禁用复合材料之间的碰撞,但这也会禁用碰撞 'inside' 复合材料。我可以用 collisionFilter.category
系统做到这一点,但它如何处理超过 32 个复合材料?
不支持复合级别的碰撞过滤,您需要在主体级别进行处理。为了使其更易于管理,只需创建一些复合辅助函数,例如compositeSetCollisionFilter(composite, filter)
并遍历 Composite.allBodies(composite)
.
关于32个类别的限制,这是由于bitwise implementation (for performance supposedly, though I doubt it matters much in reality). I've raised an issue on the project about reconsidering this。
如果您将 Matter.Detector.canCollide(filterA, filterB) 替换为您自己的可以比较两个 body.collisionFilter
对象的函数,那么现在有一种方法可以获得更多。有了这个,您可以为 body.collisionFilter
个对象使用任何您喜欢的方案。