如何使用 matterjs 制作烟雾粒子

How to make smoke particles using matterjs

我正在使用Matter.JS创建一个横向卷轴游戏,在这个游戏中,一个英雄是火做的,所以他需要一些烟雾,但我不知道如何让粒子漂浮在里面空气,如何在 Matter.JS 中制作浮体?

我想要这样的东西: https://www.youtube.com/watch?v=b-QhKcae-6E

请在此处查看我的代码笔: http://codepen.io/vanuatu/pen/VeQMpp

console.clear() 
//
var canvas = document.getElementById("canvas-container");

// Matter module aliases
var Engine          = Matter.Engine,
    World           = Matter.World,
    Body            = Matter.Body,
    Bodies          = Matter.Bodies,
    Events          = Matter.Events,
    Constraint      = Matter.Constraint,
    Composite       = Matter.Composite,
    Composites      = Matter.Composites,
    Bounds          = Matter.Bounds,
    Mouse           = Matter.Mouse,
    MouseConstraint = Matter.MouseConstraint;

// create a Matter.js engine
var engine = Engine.create(document.body, {
  enableSleeping: false, // def = false
  render: {
    options: {
      showAngleIndicator : true,
      wireframes         : true,
      showVelocity       : true,
      showCollisions     : true,
      enableSleeping     : true,
      hasBounds          : true
    }
  }
});


// add a mouse controlled constraint
var mouseConstraint = MouseConstraint.create(engine);
World.add(engine.world, mouseConstraint);

// create the ground the stack will sit on
var ground = Bodies.rectangle(200, 250, 1500, 10, { 
  isStatic: true 
});

// create the wrecking ball
var ball = Bodies.circle(260, 60, 20, { density: 1, frictionAir: 0.001});

// create the rope the ball will swing on
var ballRope = Constraint.create({
  pointA: { x: 340, y: 60 },
  bodyB: ball
});

// basket ball
var basketBall = Bodies.circle(60, 60, 20,  { restitution: 0.9 });

// bubble ball
var bubbleBall = Bodies.circle(120, 60, 40, { 
  //frictionAir: 1,
  density  : 1,
  slop     : 2,
  friction : 1
});

//
initialEngineBoundsMaxX = engine.render.bounds.max.x
initialEngineBoundsMaxY = engine.render.bounds.max.y
centerX = - 200
centerY = - 200

// 
var square = Bodies.rectangle(180, 60, 20, 20);

//
var counter = 0;
var infCounter = -1000;
Events.on(engine, 'beforeUpdate', function(event) {
  counter += 1;
  infCounter += 1;

  //
  hero = bubbleBall

  // Fallow Hero X
  engine.render.bounds.min.x = centerX + hero.bounds.min.x
  engine.render.bounds.max.x = centerX + hero.bounds.min.x + initialEngineBoundsMaxX

  // Fallow Hero Y
  engine.render.bounds.min.y = centerY + hero.bounds.min.y
  engine.render.bounds.max.y = centerY + hero.bounds.min.y + initialEngineBoundsMaxY

  //
  Mouse.setOffset(mouseConstraint.mouse, engine.render.bounds.min);


  // every 1.5 sec
  if (counter >= 60 * 1.5) {
    Body.setVelocity(basketBall, { x: 0, y: 10 });
    Body.setAngle(square, -Math.PI * 0.26);

    // reset counter
    counter = 0;
    scaleFactor = 1;
  }
});


//
Events.on(mouseConstraint, 'startdrag', function(event) {
  //console.log(event);
})

// add all of the bodies to the world
World.add(engine.world, [ball, ballRope, basketBall, bubbleBall, square, ground]);

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

//
document.body.addEventListener("keydown", function(e){ 
    speed = 10;
    switch(e.which){
      case 65:
        Body.setVelocity(hero, {x: -speed, y: 0})
        break;

      case 68:
        Body.setVelocity(hero, {x: speed, y: 0})
        break;

      case 87:
        Body.setVelocity(hero, {x: 0, y: -speed})
        break;
    }
})

我在 github 的官方存储库中提出了这个问题,@liabru 回答了我:

What you're looking for is a particle system. There's nothing currently built in to the engine for this, it's more of something you'd find in a game engine so it's a bit out of scope.

You could build your own by to defining a particle object (position, velocity, lifetime etc) and then use the engine update event to update the particle positions, then render them to the same canvas as the physics objects. The built in body type could be somewhat reusable for this (don't add it to the world, instead create your own particle world).