Jump to content

More advanced particles?


GoldFire
 Share

Recommended Posts

We are in the process of porting our Phaser-CE game to Phaser 3 and have been using Particle Storm. We were able to make a lot of great particle effects with this and it looked like the Phaser 3 particle system was fairly similar. However, we are finding some serious limitations that render the vast majority of our particle effects impossible in Phaser 3. I'm hoping this isn't actually the case and I'm just overlooking something. For example, a lot of our particles start with a random alpha value, fade in from 0 to full opacity at the half point and then back to 0 at the end:

alpha {
  value: {min: 0.5, max: 1},
  control: [{x: 0, y: 0}, {x: 0.5, y: 1}, {x: 1, y: 0}],
}

However, two issues in Phaser 3:

1. You can't use min/max in addition to start/end, so it is an either/or with having random values and values that tween.

2. You can no longer define a control, you can only provide an easing function, which means you can only either fade in or fade out, but not both.

Is there any way to accomplish this in Phaser 3 that I'm overlooking?

Link to comment
Share on other sites

With some help of some nice people in the Discord channel, we came to the conclusion that this isn't possible with the standard particle system. However, we also found that you could pass custom onEmit and onUpdate methods to the emitter, which allowed for a custom solution to add this functionality. Since we were porting from Phaser 2 with Particle Storm, I decided to write this in a way that prevented us from having to re-do all of our particle configs, so we simply include value and control in the same format and pass the following two methods as onEmit and onUpdate.

/**
 * Custom particle update callback that handles Particle Storm style controls.
 * @param  {Object} particle Particle to act on.
 * @param  {String} key      Property name.
 * @return {Number}          New value.
 */
static controlUpdate(particle, key) {
  const {control} = particle.emitter[key].propertyValue;
  const initial = particle[`${key}Initial`] || 1;
  const percent = particle.lifeT;
  let index = 0;
  let point = control[index];

  if (point.x === percent) {
    return point.y;
  }

  // Find the next point based on the current percent.
  while (point.x <= percent) {
    if (index >= control.length - 1) {
      return point.x;
    }

    index += 1;
    point = control[index];
  }

  const prev = control[index - 1];

  // Follow curve with linear interpolation: f(x) = y0 + (y1 - y0) * (x - x0) / (x1 - x0).
  const valueMulti = prev.y + (percent - prev.x) * (point.y - prev.y) / (point.x - prev.x);

  return valueMulti * initial;
}

/**
 * Custom particle emit event to set the initial value.
 * @param  {Object} particle Particle to act on.
 * @param  {String} key      Property name.
 */
static initialOnEmit(particle, key) {
  const values = particle.emitter[key].propertyValue;

  // Handle a random value.
  if (typeof values.value === 'object') {
    particle[`${key}Initial`] = randomBetween(values.value.min, values.value.max);
  } else if (values.value) {
    particle[`${key}Initial`] = values.value;
  }
}

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...