class Dust { constructor(renderingEngine = PIXI) { if (renderingEngine === undefined) throw new Error("Please assign a rendering engine in the constructor before using pixiDust.js"); //Find out which rendering engine is being used (the default is Pixi) this.renderer = ""; //If the `renderingEngine` is Pixi, set up Pixi object aliases if (renderingEngine.ParticleContainer) { this.Container = renderingEngine.Container; this.renderer = "pixi"; } //The `particles` array stores all the particles you make this.globalParticles = []; } //Random number functions randomFloat(min, max) { return min + Math.random() * (max - min); } randomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } //Use the create function to create new particle effects create( x = 0, y = 0, spriteFunction = () => console.log("Sprite creation function"), container = () => new this.Container(), numberOfParticles = 20, gravity = 0, randomSpacing = true, minAngle = 0, maxAngle = 6.28, minSize = 4, maxSize = 16, minSpeed = 0.3, maxSpeed = 3, minScaleSpeed = 0.01, maxScaleSpeed = 0.05, minAlphaSpeed = 0.02, maxAlphaSpeed = 0.02, minRotationSpeed = 0.01, maxRotationSpeed = 0.03 ) { //An array to store the curent batch of particles let particles = []; //Add the current `particles` array to the `globalParticles` array this.globalParticles.push(particles); //An array to store the angles let angles = []; //A variable to store the current particle's angle let angle; //Figure out by how many radians each particle should be separated let spacing = (maxAngle - minAngle) / (numberOfParticles - 1); //Create an angle value for each particle and push that //value into the `angles` array for (let i = 0; i < numberOfParticles; i++) { //If `randomSpacing` is `true`, give the particle any angle //value between `minAngle` and `maxAngle` if (randomSpacing) { angle = this.randomFloat(minAngle, maxAngle); angles.push(angle); } //If `randomSpacing` is `false`, space each particle evenly, //starting with the `minAngle` and ending with the `maxAngle` else { if (angle === undefined) angle = minAngle; angles.push(angle); angle += spacing; } } //A function to make particles let makeParticle = (angle) => { //Create the particle using the supplied sprite function let particle = spriteFunction(); //Display a random frame if the particle has more than 1 frame if (particle.totalFrames > 0) { particle.gotoAndStop(this.randomInt(0, particle.totalFrames - 1)); } //Set a random width and height let size = this.randomInt(minSize, maxSize); particle.width = size; particle.height = size; //Set the particle's `anchor` to its center particle.anchor.set(0.5, 0.5); //Set the x and y position particle.x = x; particle.y = y; //Set a random speed to change the scale, alpha and rotation particle.scaleSpeed = this.randomFloat(minScaleSpeed, maxScaleSpeed); particle.alphaSpeed = this.randomFloat(minAlphaSpeed, maxAlphaSpeed); particle.rotationSpeed = this.randomFloat(minRotationSpeed, maxRotationSpeed); //Set a random velocity at which the particle should move let speed = this.randomFloat(minSpeed, maxSpeed); particle.vx = speed * Math.cos(angle); particle.vy = speed * Math.sin(angle); //Push the particle into the `particles` array. //The `particles` array needs to be updated by the game loop each frame particles.push(particle); particles.push(particle); //Add the particle to its parent container container.addChild(particle); //The particle's `updateParticle` method is called on each frame of the //game loop particle.updateParticle = () => { //Add gravity particle.vy += gravity; //Move the particle particle.x += particle.vx; particle.y += particle.vy; //Change the particle's `scale` if (particle.scale.x - particle.scaleSpeed > 0) { particle.scale.x -= particle.scaleSpeed; } if (particle.scale.y - particle.scaleSpeed > 0) { particle.scale.y -= particle.scaleSpeed; } //Change the particle's rotation particle.rotation += particle.rotationSpeed; //Change the particle's `alpha` particle.alpha -= particle.alphaSpeed; //Remove the particle if its `alpha` reaches zero if (particle.alpha <= 0) { container.removeChild(particle); particles.splice(particles.indexOf(particle), 1); } }; }; //Make a particle for each angle angles.forEach(angle => makeParticle(angle)); //Return the `particles` array back to the main program return particles; } //A particle emitter emitter(interval, particleFunction) { let emitterObject = {}, timerInterval = undefined; emitterObject.playing = false; function play() { if (!emitterObject.playing) { particleFunction(); timerInterval = setInterval(emitParticle.bind(this), interval); emitterObject.playing = true; } } function stop() { if (emitterObject.playing) { clearInterval(timerInterval); emitterObject.playing = false; } } function emitParticle() { particleFunction(); } emitterObject.play = play; emitterObject.stop = stop; return emitterObject; } //A function to update the particles in the game loop update() { //Check so see if the `globalParticles` array contains any //sub-arrays if (this.globalParticles.length > 0) { //If it does, Loop through the particle arrays in reverse for (let i = this.globalParticles.length - 1; i >= 0; i--) { //Get the current particle sub-array let particles = this.globalParticles[i]; //Loop through the `particles` sub-array and update the //all the particle sprites that it contains if (particles.length > 0) { for (let j = particles.length - 1; j >= 0; j--) { let particle = particles[j]; particle.updateParticle(); } } //Remove the particle array from the `globalParticles` array if doesn't //contain any more sprites else { this.globalParticles.splice(this.globalParticles.indexOf(particles), 1); } } } } }