1
\$\begingroup\$

I'm trying to let the player of my PhaserJS game (with MatterJS physics) move a (static?) object around. That is: the player is allowed to move the object, but otherwise it should be static to the world of MatterJS. Here's a minimal scenario reproducing my situation:

class MyScene extends Phaser.Scene {
  create() {
    this.matter.add.rectangle(60, 120, 100, 10).isStatic = true;
    this.matter.add.pointerConstraint({ /* solve it here?! */ });
  }
  
  dropBall() {
    this.matter.add.circle(150, 20, 10);
  }
}

const game = new Phaser.Game({
  banner: false,
  width: 300,
  height: 150,
  physics: {
    default: 'matter',
    matter: { debug: true, setBounds: true },
  },
  scene: [MyScene]
});

document.addEventListener("DOMContentLoaded", () => {
  document.getElementById("start").addEventListener("click", () => {
    game.scene.getScenes(false)[0]?.dropBall();
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/3.55.2/phaser.min.js"></script>
<div>1. Move platform to middle. 2. Then <button id="start">Drop a ball!</button></div>

I want the player to only be able to move the static rectangle around with the mouse. Technically the ball-dropping feature in my example is not needed for the question, but I'd hope it gives some context. Plus it shows that the pointerConstraint does something because you now can move the balls around (which shouldn't be possible).

\$\endgroup\$
2
  • \$\begingroup\$ In other physics engines, this would usually be implemented as a kinematic body - one that can push other objects but not be pushed itself, outside of code that directly changes its position. Searching for "matter-js kinematic" turns up some threads on achieving something similar in this library. \$\endgroup\$
    – DMGregory
    Mar 1 at 14:24
  • \$\begingroup\$ Thanks! I'm new to game development and knowing the terminology already helps! Will see if the workarounds in that issue could help me out as well. \$\endgroup\$
    – Jeroen
    Mar 1 at 15:08

1 Answer 1

2
\$\begingroup\$

If you want to use the builtin phaser functions, you just need to create a phaser-matter-gameboject, like an image (link to the documentation), and that you configer it to be draggable.

  1. create matter-image
  2. make image interactive setInteractive
  3. make image draggable this.input.setDraggable(...)
  4. in the drag Event update the position of the image

Here a short demo, showcasing this:
(based on your codesnippet)

class MyScene extends Phaser.Scene {
  create() {
    // START - just creating an image for the demo  
    let graphics  = this.make.graphics();
    graphics.fillStyle(0xffffff);
    graphics.fillRect(0, 0, 100, 10);
    graphics.generateTexture('paddle', 100, 10);
    // END - just creating an image for the demo  

    let paddle = this.matter.add.image(60, 120, 'paddle').setStatic(true);
    
    paddle.setInteractive();
    this.input.setDraggable(paddle);

    this.input.on('drag', function (pointer, gameObject, dragX, dragY) {
        paddle.x = dragX;
        paddle.y = dragY;
    });
  }
  
  dropBall() {
    this.matter.add.circle(150, 20, 10);
  }
}

const game = new Phaser.Game({
  banner: false,
  width: 300,
  height: 150,
  physics: {
    default: 'matter',
    matter: { debug: true, setBounds: true },
  },
  scene: [MyScene]
});

document.addEventListener("DOMContentLoaded", () => {
  document.getElementById("start").addEventListener("click", () => {
    game.scene.getScenes(false)[0]?.dropBall();
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/3.55.2/phaser.min.js"></script>
<div>1. Move platform to middle. 2. Then <button id="start">Drop a ball!</button></div>

\$\endgroup\$
1
  • \$\begingroup\$ Woa! So confusing that .add.rectangle(...) is functionally different from .add.image(...). Your answer is excactly the effect I was after. Thanks! \$\endgroup\$
    – Jeroen
    Mar 6 at 8:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .