Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sprite image not appearing on matter.js

I am trying to replace the standard circle body with an image sprite but it isn't showing the image.

var Engine = Matter.Engine,
  Render = Matter.Render,
  World = Matter.World,
  Bodies = Matter.Bodies,
  Body = Matter.Body,
  Constraint = Matter.Constraint,
  Vector = Matter.Vector,
  Events = Matter.Events,
  Mouse = Matter.Mouse,
  MouseConstraint = Matter.MouseConstraint;

// create an engine
var engine = Engine.create();

engine.world.gravity.y = 0; // gravity not needed in this app

// create a renderer
var render = Render.create({
  element: document.body,
  engine: engine
});

var ball_0 = Bodies.circle(100, 100, 11, {
  density: 0.04,
  frictionAir: 0.06,
  restitution: 0.8,
  friction: 0.01,
  render: {
    sprite: {
      texture: 'images/white.png',
      xScale: 20,
      yScale: 20
    }
  }
});

// add all of the bodies to the world
World.add(engine.world, ball_0);

// run the engine
Engine.run(engine);

// run the renderer
Render.run(render);
<script src="https://github.com/liabru/matter-js/releases/download/0.10.0/matter.min.js"></script>
like image 346
Danny Cullen Avatar asked Oct 26 '25 21:10

Danny Cullen


2 Answers

You are drawing everything in wireframe. Change your Render.create() call to turn off wireframes with options: {wireframes: false}:

// create a renderer
var render = Render.create({
  element: document.body,
  engine: engine,
  options: {wireframes: false}
});
like image 94
zero298 Avatar answered Oct 28 '25 10:10

zero298


Setting wireframes: false is half the answer, you also need to first load the image before setting it as texture

You must load the Image before setting it as Texture otherwise you will get error

HTMLImageElement is in "broken" state

For me this issue end up printing 900+ error messages which crashed my sandbox.

Solution: I created a simple Image loader:

const loadImage = (url, onSuccess, onError) => {
  const img = new Image();
  img.onload = () => {
    onSuccess(img.src);
  };
  img.onerror = onError();
  img.src = url;
};

And later I used that loader to load the texture. Once texture is loaded you can set it as texture for your Body objects.

 loadImage(
      "./assets/blue.jpg",
      url => {
        console.log("Success");
        World.add(world, [
          Bodies.circle(340, 340, 100, {
            density: 0.0005,
            frictionAir: 0.06,
            restitution: 0.3,
            friction: 0.01,
            render: {
              sprite: {
                texture: url // set texture here
              }
            }
          })
        ]);
      },
      () => {
        console.log("Error  Loading ");
      }
    );

Important: before calling Renderer.run() you must disable wireframes

// create renderer
var render = Render.create({
  element: document.body,
  engine: engine,
  options: {
    width: 800,
    height: 600,
    wireframes: false, // disable Wireframe
  }
});

Render.run(render);
like image 31
Hitesh Sahu Avatar answered Oct 28 '25 10:10

Hitesh Sahu