I want to have my particle emitter rotate the emitted particle in the direction angle it is moving.
The spritesheet I am using-
What I am getting -
What I want to achieve -
I want to have my particle emitter rotate the emitted particle in the direction angle it is moving.
The spritesheet I am using-
What I am getting -
What I want to achieve -
rotate: { onEmit: updateParticleRotation, onUpdate: updateParticleRotation },
Thank you Samme ,this is want i needed.
Nice, I was about to post the same question.
Just want to add that you can combine 2 or more Phaser particle emitters for some pretty cool effects. A lot of Nintendo and arcade games have these types of particle effects, see the example screenshot below
@samme quick follow-up question.
I was able to use your code example using onEmit
and onUpdate
on the particle. See the code example below it is modified from this example, you can copy&paste it in the Phaser sandbox
The explosion lines emitter uses the onUpdate
call, meaning it will be called every frame. But it only needs to be called once to set the angle and then it doesn’t change. However, when I change onUpdate
to onEmit
the angles aren’t correct. It looks like it uses a sprite-pool and the angle is based on the previous (re-used) particle velocity.
So is there any way to only use onEmit
and not onUpdate
? Not sure if it impacts the performance that much, but I figure it’s always something.
class Example extends Phaser.Scene
{
preload ()
{
this.load.atlas('flares', 'assets/particles/flares.png', 'assets/particles/flares.json');
}
create ()
{
// big flash particle
this.emit_blast = this.add.particles(0, 0, 'flares', {
frame: [ 'red', 'yellow', 'green' ],
lifespan: 100,
scale: { min: 4.0, max: 6.0 },
blendMode: 'ADD',
emitting: false
});
// smaller falling particles
this.emit_particles = this.add.particles(0, 0, 'flares', {
frame: [ 'red', 'yellow', 'green' ],
lifespan: 4000,
speed: { min: 150, max: 250 },
scale: { start: 0.8, end: 0 },
gravityY: 150,
blendMode: 'ADD',
emitting: false
});
// explosion streaks, lines in angled in move direction
this.emit_sparks = this.add.particles(0, 0, 'flares', {
frame: [ 'red', 'yellow', 'green' ],
lifespan: 1000,
speed: { min: 500, max: 1000 },
scaleX: 3.0,
scaleY: 0.2,
rotate: { onUpdate: function(p) { return Phaser.Math.RadToDeg(Math.atan2(p.velocityY, p.velocityX)); } },
blendMode: 'ADD',
emitting: false
});
// click mouse for explosion
this.input.on('pointerdown', function(pointer) {
this.doExplosion(pointer.x, pointer.y);
}.bind(this));
this.add.text(10, 10, 'Click to explode emit particles');
}
doExplosion(x, y)
{
this.emit_blast.explode(3, x, y); // one big blast circle
this.emit_particles.explode(12, x, y); // explosion particles
this.emit_sparks.explode(8, x, y); // explosion lines
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
The problem with onEmit
is that for most properties it’s called before the particle velocity is set.
An alternative is to use a custom Particle class (particleClass
):
class AngledParticle extends Phaser.GameObjects.Particles.Particle {
fire(x, y) {
const isAlive = super.fire(x, y);
this.rotation = Math.atan2(this.velocityY, this.velocityX);
this.angle = Phaser.Math.RadToDeg(this.rotation);
return isAlive;
}
}
this.emit_sparks = this.add.particles(0, 0, 'flares', {
particleClass: AngledParticle,
// etc.
});
@samme Thanks for the tip, that looks very useful. I think it could also be used for other effects, like the particles starting in evenly spaced out (instead of random) or in a ring formation away from the center etc.
However, I couldn’t get the class to work, I mean how do I hook the AngledParticle
up to an emitter? I’ve found other documentation here but no mention of how add it to emitters.
I left that out, sorry. You pass it as particleClass
in the particle emitter config (edited above).
@samme Ah I see thanks. Using a custom particle class opens up all kind of possibilities for new effects.
When an emitter calls .explode(16)
to create 16 particles, is there a way to read the explosion index from inside the particle? So that from inside the onEmit
or fire
method, the particle can somehow know its sequence order in the explosion, so for example that it is the 5th particle?
I’m asking because I’m looking for a way to create a perfect circle (or star shape etc) of exploding particles. It could be done using the Math.sin
and Math.cos
in the particles, to set their initial location, but you’d need the index or order nr of the particle.
No, but if you call emitParticle(1, x, y) you could track this yourself.
However, you can also use explode()
with Emit Zone shapes. Set an emitter quantity
equal to the zone quantity
and use a long lifespan
, for example.
I forgot there’s emitCallback
, which is easier than using a custom particle class.
this.emit_sparks = this.add.particles(0, 0, 'flares', {
// etc.
emitCallback: (particle) => {
particle.angle = Phaser.Math.RadToDeg(
Math.atan2(particle.velocityY, particle.velocityX)
);
}
});