猿问

如何更改对象的碰撞过滤器,使其不再与 MouseConstraint (MatterJS) 交互

我正在制作Slingshot演示。问题是,在发射岩石后,仍然可以单击并拖动它,我想禁用它。

我在岩石上添加了一个过滤器:


var rockOptions = {

  density: 0.004,

  restitution: 0.75,

  collisionFilter: { mask: SOLID, category: NEXTBALL }

};

以及鼠标约束:


var mouse = Mouse.create(render.canvas),

  mouseConstraint = MouseConstraint.create(engine, {

    mouse: mouse,

    collisionFilter: { category: NEXTBALL },

    constraint: {

      stiffness: 0.2,

      render: {

        visible: true

      }

    }

  });

然后在单击事件中我尝试更改该过滤器,因此它不应再与鼠标类别匹配:


Events.on(engine, "afterUpdate", function () {

  if (

    mouseConstraint.mouse.button === -1 &&

    (rock.position.x > shootPosition.x + 20 ||

      rock.position.y < shootPosition.y - 20)

  ) {

    Composite.remove(engine.world, elastic);


    rock.collisionFilter = {category: SOLID, mask: SOLID};

  }

});

但它仍然是可拖动的。我猜问题是我如何更改岩石上的过滤器,但我在文档中没有看到任何建议更改它的方法。


我不认为这是因为我设置的类别,但在这里它们只是为了以防万一(实体和图像的确实有效,球不会与图像的碰撞:


const SOLID = 0x0001;

const IMAGE = 0x0002;

const NEXTBALL = 0x0003;

帮我让岩石不再可点击


守着一只汪
浏览 189回答 2
2回答

小怪兽爱吃肉

防止鼠标操纵已经射击的岩石可以通过 // <---下面代码片段中所示的两个简单更改来实现。rock.collisionFilter.category = 0b10;将刚刚发射的任何岩石的类别设置为 2,然后创建新的岩石并rock用要发射的下一块岩石覆盖变量。collisionFilter: {mask: 0b1},将鼠标约束上的遮罩设置为仅与类别 1 中的实体交互。由于禁用的岩石属于类别 2 ( 0b10),因此鼠标将不再与它们交互。这是上下文中的代码。我使用这个提交以防万一发生任何变化。Events.on(engine, 'afterUpdate', function() {  if (mouseConstraint.mouse.button === -1 && (rock.position.x > 190 || rock.position.y < 430)) {    rock.collisionFilter.category = 0b10; // <---    rock = Bodies.polygon(170, 450, 7, 20, rockOptions);    Composite.add(engine.world, rock);    elastic.bodyB = rock;  }});// add mouse controlvar mouse = Mouse.create(render.canvas),  mouseConstraint = MouseConstraint.create(engine, {    mouse: mouse,    collisionFilter: {mask: 0b1}, // <---    constraint: {      stiffness: 0.2,      render: {        visible: false      }    }  });默认mask值为 32 位全部设置,或4294967295/ 0xffffffff。您可能希望更精确,并仅禁用鼠标约束的第二位:0xfffffffd。这使得鼠标可以与除类别 2 之外的任何对象交互,而不仅仅是与类别 1 交互。

拉风的咖菲猫

经过多次重新开始、调整和检查不同的演示后,终于弄清楚了。首先,类别的位掩码必须是 2 的幂,因此NEXTBALL必须是0x0004而不是0x0003。接下来,您不能将整个collisionFilter对象设置在已建立的实体上,否则会破坏碰撞。相反,你必须使用rock.collisionFilter.category = NEXTBALL;
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答