10

I have some code like the following for the matter.js library:

// create two boxes and a ground
var boxA = Bodies.rectangle(400, 200, 80, 80);
var boxB = Bodies.rectangle(450, 50, 80, 80);
var ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true });

// add all of the bodies to the world
World.add(engine.world, [boxA, boxB, ground]);
Events.on(engine, 'tick', function(event) {
  if (mouseConstraint.mouse.button == 0){
    alert("what is clicked?");
  }
});

Is there a way I can tell if boxA or boxB has been clicked with the mouse in the event handler?

ggorlen
  • 44,755
  • 7
  • 76
  • 106
Ian
  • 900
  • 2
  • 9
  • 19

2 Answers2

2

To elaborate on this answer, here's a runnable example of using mouseConstraint.body in your event handler to determine which body is being clicked:

const engine = Matter.Engine.create();
const render = Matter.Render.create({
  element: document.body,
  engine: engine,
});
const bodies = [
  Matter.Bodies.rectangle(
    400, 310, 810, 60, {isStatic: true, angle: 0.0}
  ),
  ...[...Array(100)].map(() =>
    Matter.Bodies.rectangle(
      Math.random() * 400,     // x
      Math.random() * 100,     // y
      Math.random() * 50 + 10, // w
      Math.random() * 50 + 10, // h
      {angle: Math.random() * (Math.PI * 2)},
    )
  ),
];
const mouseConstraint = Matter.MouseConstraint.create(
  engine, {element: document.body}
);
const runner = Matter.Runner.create();
Matter.Events.on(runner, "tick", event => {
  if (mouseConstraint.body) {
    Matter.Composite.remove(engine.world, mouseConstraint.body);
  }
});
// also possible, testing the condition on mousedown only:
//Matter.Events.on(mouseConstraint, "mousedown", () => {
//  if (mouseConstraint.body) {
//    Matter.Composite.remove(engine.world, mouseConstraint.body);
//  }
//});
Matter.Composite.add(engine.world, [...bodies, mouseConstraint]);
Matter.Runner.start(runner, engine);
Matter.Render.run(render);
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.js"></script>

You can also use Matter.Query.point and pass in the mouse X and Y position on click to obtain an array of bodies at that point.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
  • Note that this does not work with the mouseup event. Testing the mouseConstraint.body property on mouseup always shows that it is not set. This tripped me up for a while, but it makes sense because when the mouse button is up, no body is currently being touched, as the mouse click has just ended. My solution was to test on mousedown, as shown above. – Mike Nov 17 '22 at 18:01
0

mouseConstraint.body contains the body that was clicked.

tomdemuyt
  • 4,572
  • 2
  • 31
  • 60