0

I made a BallCabin with Matter.js in DOM (render BallCabin on div element), it perform OK. But same code, when I put it into pixi.js project, I found nothing is displayed. I'd like to how can I render Matter.js in pixi.js project. Sorry for poor English... and thanks for all reply!

The following is my code:

  1. window.game.view is the root element (canvas) in pixi program (reference for Application.view), I thought I may render BallCabin on the canvas.
  2. Ticker.shared.add(this.update, this) to call update function.
export class BallCabin extends Sprite{
  constructor() {
    super();

    this._world = null;
    this._engine = null;
    this._cabin = null;
    this._balls = [];

    this.BALL_RADIUS = 12;

    this.initView();
  }

  initView() {
    this.initScene();
    this.makeCabin();
    this.makeSensors();
    this.makeBalls();
    this.initAction();
  }

  initScene() {
    const element = window.game.view;

    this._engine = Engine.create();
    let runner = Runner.create();
    let render = Render.create({
      background: '#6eb543',
      element: element,
      engine: this._engine,
      options: {
        width: 300,
        height: 300,
        background: 'transparent',
        wireframes: false,
        showIds: false
      }
    });
    this._world = this._engine.world;

    Render.run(render);
    Runner.run(runner, this._engine);
  }

  initAction() {
    Events.on(this._engine, 'collisionStart', (evt) => this.onCollision(evt));
    Ticker.shared.add(this.update, this);
  }

  makeCabin() {
    let parts = [];
    let pt = {x: 150, y: 150};

    for (let i = 0; i < 90; i++) {
      let x = pt.x + Math.cos(i * 4 * Math.PI / 180) * 120;
      let y = pt.y + Math.sin(i * 4 * Math.PI / 180) * 120;
      let options = {friction: 0.5, angle: Math.PI / 180 * i * 4, render: {fillStyle: i !== 0 ? '#2E2D34' : '#FFFFFF'}};
      let rec = Bodies.rectangle(x, y, 10, 12, options);
      parts.push(rec);
      Composite.add(this._world, rec);
    }

    this._cabin = Body.create({parts, isStatic: true});
  }

  makeSensors() {
    const pt = {x: 150, y: 150};
    const ary = [];

    for (let i = 20; i < 45; i++) {
      const x = pt.x + Math.cos(i * 4 * Math.PI / 180) * 120;
      const y = pt.y + Math.sin(i * 4 * Math.PI / 180) * 120;
      const render = {strokeStyle: '#C44D58', fillStyle: 'transparent', lineWidth: 1};
      const options = {isSensor: true, isStatic: true, friction: 0, label: 'addSpeedSensor', angle: Math.PI / 180 * i * 4, render: render};

      let rec = Bodies.rectangle(x, y, 30, 30, options);
      ary.push(rec);
      Composite.add(this._world, rec);
    }
  }

  makeBalls() {
    let pt = {x: 150, y: 150};

    for (let i = 0; i < 10; i++) {
      let x = pt.x - 65 + i * 5;
      let y = pt.y - 65 + i * 5;
      let options = {isStatic: false, mass: 1 + i * 2, friction: 0, frictionStatic: 0, label: 'ball', render: {opacity: 0.6,}, collisionFilter: {category: 0x0002, mask: 0x0002 | 0x0001}};

      const ball = Bodies.circle(x, y, this.BALL_RADIUS, options);
      this._balls.push(ball);
    }

    for (let i = 0; i < 15; i++) {
      let x = pt.x - 65 + i * 5;
      let y = pt.y - 65 + i * 5;
      let options = {isStatic: false, mass: 1 + i * 2, friction: 0, frictionStatic: 0, label: 'ball', render: {opacity: 1,}, collisionFilter: {category: 0x0004, mask: 0x0004 | 0x0001}};

      const ball = Bodies.circle(x, y, this.BALL_RADIUS, options);
      this._balls.push(ball);
    }
    Composite.add(this._world, this._balls);
  }

  onCollision(evt) {
    let pairs = evt.pairs;
    for (let i = 0, j = pairs.length; i != j; ++i) {
      let pair = pairs[i];
      let {bodyA, bodyB} = pair;

      if (bodyA.label === 'addSpeedSensor') {
        Body.setVelocity(bodyB, {x: -6, y: -5});
        //Body.applyForce(bodyB, bodyB.position, {x: 0.3, y: 0.5})
      } else if (bodyB.label === 'addSpeedSensor') {
        // Body.applyForce(bodyA, {x: bodyA.position.x, y: bodyA.position.y}, {x: -0.1, y: -0.05})
      }
    }
  }

  update(deltaTime) {
    //super.update(delta);
    if (this._cabin) {
      Body.rotate(this._cabin, Math.PI / 120);
    }
  }
}
  • I don't know anything about pixi, but looks like you're using the MJS internal renderer. Just a guess, but I imagine you'll want to use pixi as the renderer, which means running MJS headlessly (as a pure physics engine, not a renderer). I have many examples of how to do this with other renderers like p5, React, HTML5 canvas and the DOM, so I imagine you'll be able to plug in pixi with a few small modifications. Take [this](https://stackoverflow.com/questions/63906218/using-matter-js-to-render-to-the-dom-or-react/65354225#65354225) for example. – ggorlen Mar 24 '23 at 13:22

0 Answers0