Skip to content

Commit 50981fd

Browse files
committed
Emitter now has minParticleAlpha and maxParticleAlpha values for setting a random alpha on emitted particles.
Emitter.particleAnchor allows you to control the anchor of emitted Particles. Defaults to 0.5 (same as before) but now under your control. Emitter now emits Phaser.Particle objects instead of Phaser.Sprites, which can be extended as required. Emitter has had various local properties removed that were already declared in Phaser.Group which it extends.
1 parent 73d0414 commit 50981fd

6 files changed

Lines changed: 150 additions & 49 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ Updated
8080
* Keyboard.stop nulls the function references after removing the event listeners (thanks @bmceldowney, #691)
8181
* Tilemap.hasTile allows for multi-layer type parameter (thanks @Raeven0, #680)
8282
* Grunt update to dev dependencies (thanks @xtian, #695)
83+
* Emitter now emits Phaser.Particle objects instead of Phaser.Sprites, which can be extended as required.
84+
* Emitter has had various local properties removed that were already declared in Phaser.Group which it extends.
8385

8486

8587
New Features
@@ -101,6 +103,8 @@ New Features
101103
* Tilemap.removeTile(x, y, layer) lets you remove the tile at the given coordinates and updates the collision data.
102104
* Tilemap.removeTileWorldXY lets you remove the tile at the given pixel value coordinates and updates the collision data.
103105
* Key.enabled boolean allows you to toggle if a Key processes its update method or dispatches any events without deleting and re-creating it.
106+
* Emitter now has minParticleAlpha and maxParticleAlpha values for setting a random alpha on emitted particles.
107+
* Emitter.particleAnchor allows you to control the anchor of emitted Particles. Defaults to 0.5 (same as before) but now under your control.
104108

105109

106110
Bug Fixes

build/config.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
<script src="$path/src/gameobjects/RenderTexture.js"></script>
119119
<script src="$path/src/gameobjects/SpriteBatch.js"></script>
120120
<script src="$path/src/gameobjects/RetroFont.js"></script>
121+
<script src="$path/src/gameobjects/Particle.js"></script>
121122
122123
<script src="$path/src/system/Canvas.js"></script>
123124
<script src="$path/src/system/Device.js"></script>

src/gameobjects/Particle.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* @author Richard Davey <rich@photonstorm.com>
3+
* @copyright 2014 Photon Storm Ltd.
4+
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
5+
*/
6+
7+
/**
8+
* @class Phaser.Particle
9+
*
10+
* @classdesc Create a new `Particle` object. Particles are extended Sprites that are emitted by a particle emitter.
11+
*
12+
* @constructor
13+
* @extends Phaser.Sprite
14+
* @param {Phaser.Game} game - A reference to the currently running game.
15+
* @param {number} x - The x coordinate (in world space) to position the Sprite at.
16+
* @param {number} y - The y coordinate (in world space) to position the Sprite at.
17+
* @param {string|Phaser.RenderTexture|Phaser.BitmapData|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture.
18+
* @param {string|number} frame - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.
19+
*/
20+
Phaser.Particle = function (game, x, y, key, frame) {
21+
22+
Phaser.Sprite.call(this, game, x, y, key, frame);
23+
24+
}
25+
26+
Phaser.Particle.prototype = Object.create(Phaser.Sprite.prototype);
27+
Phaser.Particle.prototype.constructor = Phaser.Particle;
28+
29+
/**
30+
* Override and use this function in your own custom objects to handle any update requirements you may have.
31+
*
32+
* @method Phaser.Particle#update
33+
* @memberof Phaser.Particle
34+
*/
35+
Phaser.Particle.prototype.update = function() {
36+
37+
38+
39+
};

src/gameobjects/Sprite.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,10 +280,10 @@ Phaser.Sprite.prototype.preUpdate = function() {
280280
}
281281

282282
// Update any Children
283-
// for (var i = 0, len = this.children.length; i < len; i++)
284-
// {
285-
// this.children[i].preUpdate();
286-
// }
283+
for (var i = 0, len = this.children.length; i < len; i++)
284+
{
285+
this.children[i].preUpdate();
286+
}
287287

288288
return true;
289289

src/particles/arcade/Emitter.js

Lines changed: 101 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) {
4444
* @property {number} x - The X position of the top left corner of the emitter in world space.
4545
* @default
4646
*/
47-
this.x = 0;
47+
// this.x = 0;
4848

4949
/**
5050
* @property {number} y - The Y position of the top left corner of emitter in world space.
5151
* @default
5252
*/
53-
this.y = 0;
53+
// this.y = 0;
5454

5555
/**
5656
* @property {number} width - The width of the emitter. Particles can be randomly generated from anywhere within this box.
@@ -100,17 +100,29 @@ Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) {
100100
*/
101101
this.maxRotation = 360;
102102

103+
/**
104+
* @property {number} minParticleAlpha - The minimum possible alpha value of a particle.
105+
* @default
106+
*/
107+
this.minParticleAlpha = 1;
108+
109+
/**
110+
* @property {number} maxParticleAlpha - The maximum possible alpha value of a particle.
111+
* @default
112+
*/
113+
this.maxParticleAlpha = 1;
114+
103115
/**
104116
* @property {number} gravity - Sets the `body.gravity.y` of each particle sprite to this value on launch.
105117
* @default
106118
*/
107119
this.gravity = 100;
108120

109121
/**
110-
* @property {any} particleClass - For emitting your own particle class types. They must extend Phaser.Sprite.
122+
* @property {any} particleClass - For emitting your own particle class types. They must extend Phaser.Particle.
111123
* @default
112124
*/
113-
this.particleClass = Phaser.Sprite;
125+
this.particleClass = Phaser.Particle;
114126

115127
/**
116128
* @property {Phaser.Point} particleDrag - The X and Y drag component of particles launched from the emitter.
@@ -136,10 +148,44 @@ Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) {
136148
this.lifespan = 2000;
137149

138150
/**
139-
* @property {Phaser.Point} bounce - How much each particle should bounce on each axis. 1 = full bounce, 0 = no bounce.
151+
* @property {Phaser.Point} bounce - How much each particle should bounce on each axis. 1 = full bounce, 0 = no bounce.
140152
*/
141153
this.bounce = new Phaser.Point();
142154

155+
/**
156+
* @property {boolean} on - Determines whether the emitter is currently emitting particles. It is totally safe to directly toggle this.
157+
* @default
158+
*/
159+
this.on = false;
160+
161+
/**
162+
* @property {Phaser.Point} particleAnchor - When a particle is created its anchor will be set to match this Point object (defaults to x/y: 0.5 to aid in rotation)
163+
* @default
164+
*/
165+
this.particleAnchor = new Phaser.Point(0.5, 0.5);
166+
167+
/**
168+
* @property {boolean} exists - Determines whether the emitter is being updated by the core game loop.
169+
* @default
170+
*/
171+
// this.exists = true;
172+
173+
/**
174+
* The point the particles are emitted from.
175+
* Emitter.x and Emitter.y control the containers location, which updates all current particles
176+
* Emitter.emitX and Emitter.emitY control the emission location relative to the x/y position.
177+
* @property {number} emitX
178+
*/
179+
this.emitX = x;
180+
181+
/**
182+
* The point the particles are emitted from.
183+
* Emitter.x and Emitter.y control the containers location, which updates all current particles
184+
* Emitter.emitX and Emitter.emitY control the emission location relative to the x/y position.
185+
* @property {number} emitY
186+
*/
187+
this.emitY = y;
188+
143189
/**
144190
* @property {number} _quantity - Internal helper for deciding how many particles to launch.
145191
* @private
@@ -170,34 +216,6 @@ Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) {
170216
*/
171217
this._frames = null;
172218

173-
/**
174-
* @property {boolean} on - Determines whether the emitter is currently emitting particles. It is totally safe to directly toggle this.
175-
* @default
176-
*/
177-
this.on = false;
178-
179-
/**
180-
* @property {boolean} exists - Determines whether the emitter is being updated by the core game loop.
181-
* @default
182-
*/
183-
this.exists = true;
184-
185-
/**
186-
* The point the particles are emitted from.
187-
* Emitter.x and Emitter.y control the containers location, which updates all current particles
188-
* Emitter.emitX and Emitter.emitY control the emission location relative to the x/y position.
189-
* @property {boolean} emitX
190-
*/
191-
this.emitX = x;
192-
193-
/**
194-
* The point the particles are emitted from.
195-
* Emitter.x and Emitter.y control the containers location, which updates all current particles
196-
* Emitter.emitX and Emitter.emitY control the emission location relative to the x/y position.
197-
* @property {boolean} emitY
198-
*/
199-
this.emitY = y;
200-
201219
};
202220

203221
Phaser.Particles.Arcade.Emitter.prototype = Object.create(Phaser.Group.prototype);
@@ -211,6 +229,13 @@ Phaser.Particles.Arcade.Emitter.prototype.update = function () {
211229

212230
if (this.on)
213231
{
232+
var i = this.children.length;
233+
234+
while (i--)
235+
{
236+
this.children[i].update();
237+
}
238+
214239
if (this._explode)
215240
{
216241
this._counter = 0;
@@ -248,13 +273,14 @@ Phaser.Particles.Arcade.Emitter.prototype.update = function () {
248273
};
249274

250275
/**
251-
* This function generates a new array of particle sprites to attach to the emitter.
276+
* This function generates a new set of particles for use by this emitter.
277+
* The particles are stored internally waiting to be emitted via Emitter.start.
252278
*
253279
* @method Phaser.Particles.Arcade.Emitter#makeParticles
254280
* @param {array|string} keys - A string or an array of strings that the particle sprites will use as their texture. If an array one is picked at random.
255-
* @param {array|number} frames - A frame number, or array of frames that the sprite will use. If an array one is picked at random.
256-
* @param {number} quantity - The number of particles to generate.
257-
* @param {boolean} [collide=false] - Sets the checkCollision.none flag on the particle sprites body.
281+
* @param {array|number} [frames=0] - A frame number, or array of frames that the sprite will use. If an array one is picked at random.
282+
* @param {number} [quantity] - The number of particles to generate. If not given it will use the value of Emitter.maxParticles.
283+
* @param {boolean} [collide=false] - If you want the particles to be able to collide with other Arcade Physics bodies then set this to true.
258284
* @param {boolean} [collideWorldBounds=false] - A particle can be set to collide against the World bounds automatically and rebound back into the World if this is set to true. Otherwise it will leave the World.
259285
* @return {Phaser.Particles.Arcade.Emitter} This Emitter instance.
260286
*/
@@ -301,9 +327,7 @@ Phaser.Particles.Arcade.Emitter.prototype.makeParticles = function (keys, frames
301327

302328
particle.exists = false;
303329
particle.visible = false;
304-
305-
// Center the origin for rotation assistance
306-
particle.anchor.set(0.5);
330+
particle.anchor.copyFrom(this.particleAnchor);
307331

308332
this.add(particle);
309333

@@ -316,6 +340,7 @@ Phaser.Particles.Arcade.Emitter.prototype.makeParticles = function (keys, frames
316340

317341
/**
318342
* Call this function to turn off all the particles and the emitter.
343+
*
319344
* @method Phaser.Particles.Arcade.Emitter#kill
320345
*/
321346
Phaser.Particles.Arcade.Emitter.prototype.kill = function () {
@@ -328,6 +353,7 @@ Phaser.Particles.Arcade.Emitter.prototype.kill = function () {
328353

329354
/**
330355
* Handy for bringing game objects "back to life". Just sets alive and exists back to true.
356+
*
331357
* @method Phaser.Particles.Arcade.Emitter#revive
332358
*/
333359
Phaser.Particles.Arcade.Emitter.prototype.revive = function () {
@@ -340,16 +366,16 @@ Phaser.Particles.Arcade.Emitter.prototype.revive = function () {
340366
/**
341367
* Call this function to start emitting particles.
342368
* @method Phaser.Particles.Arcade.Emitter#start
343-
* @param {boolean} [explode=true] - Whether the particles should all burst out at once.
344-
* @param {number} [lifespan=0] - How long each particle lives once emitted. 0 = forever.
369+
* @param {boolean} [explode=true] - Whether the particles should all burst out at once (true) or at the frequency given (false).
370+
* @param {number} [lifespan=0] - How long each particle lives once emitted in ms. 0 = forever.
345371
* @param {number} [frequency=250] - Ignored if Explode is set to true. Frequency is how often to emit a particle in ms.
346372
* @param {number} [quantity=0] - How many particles to launch. 0 = "all of the particles".
347373
*/
348374
Phaser.Particles.Arcade.Emitter.prototype.start = function (explode, lifespan, frequency, quantity) {
349375

350376
if (typeof explode === 'undefined') { explode = true; }
351377
if (typeof lifespan === 'undefined') { lifespan = 0; }
352-
if (typeof frequency === 'undefined') { frequency = 250; }
378+
if (typeof frequency === 'undefined' || frequency === null) { frequency = 250; }
353379
if (typeof quantity === 'undefined') { quantity = 0; }
354380

355381
this.revive();
@@ -376,7 +402,8 @@ Phaser.Particles.Arcade.Emitter.prototype.start = function (explode, lifespan, f
376402
};
377403

378404
/**
379-
* This function can be used both internally and externally to emit the next particle.
405+
* This function can be used both internally and externally to emit the next particle in the queue.
406+
*
380407
* @method Phaser.Particles.Arcade.Emitter#emitParticle
381408
*/
382409
Phaser.Particles.Arcade.Emitter.prototype.emitParticle = function () {
@@ -447,6 +474,11 @@ Phaser.Particles.Arcade.Emitter.prototype.emitParticle = function () {
447474
particle.frame = this._frames;
448475
}
449476

477+
if (this.minParticleAlpha !== 1 || this.maxParticleAlpha !== 1)
478+
{
479+
particle.alpha = this.game.rnd.realInRange(this.minParticleAlpha, this.maxParticleAlpha);
480+
}
481+
450482
particle.body.gravity.y = this.gravity;
451483
particle.body.drag.x = this.particleDrag.x;
452484
particle.body.drag.y = this.particleDrag.y;
@@ -515,10 +547,29 @@ Phaser.Particles.Arcade.Emitter.prototype.setRotation = function (min, max) {
515547

516548
};
517549

550+
/**
551+
* A more compact way of setting the alpha constraints of the emitter.
552+
*
553+
* @method Phaser.Particles.Arcade.Emitter#setAlpha
554+
* @param {number} [min=1] - The minimum value for this range.
555+
* @param {number} [max=1] - The maximum value for this range.
556+
*/
557+
Phaser.Particles.Arcade.Emitter.prototype.setAlpha = function (min, max) {
558+
559+
if (typeof min === 'undefined') { min = 1; }
560+
if (typeof max === 'undefined') { max = 1; }
561+
562+
this.minParticleAlpha = min;
563+
this.maxParticleAlpha = max;
564+
565+
};
566+
518567
/**
519568
* Change the emitters center to match the center of any object with a `center` property, such as a Sprite.
569+
* If the object doesn't have a center property it will be set to object.x + object.width / 2
570+
*
520571
* @method Phaser.Particles.Arcade.Emitter#at
521-
* @param {object|Phaser.Sprite} object - The object that you wish to match the center with.
572+
* @param {object|Phaser.Sprite|Phaser.Image|Phaser.TileSprite|Phaser.Text|PIXI.DisplayObject} object - The object that you wish to match the center with.
522573
*/
523574
Phaser.Particles.Arcade.Emitter.prototype.at = function (object) {
524575

@@ -527,6 +578,11 @@ Phaser.Particles.Arcade.Emitter.prototype.at = function (object) {
527578
this.emitX = object.center.x;
528579
this.emitY = object.center.y;
529580
}
581+
else
582+
{
583+
this.emitX = object.world.x + (object.anchor.x * object.width);
584+
this.emitY = object.world.y + (object.anchor.y * object.height);
585+
}
530586

531587
};
532588

tasks/manifests/phaser.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"src/gameobjects/RenderTexture.js",
5252
"src/gameobjects/SpriteBatch.js",
5353
"src/gameobjects/RetroFont.js",
54+
"src/gameobjects/Particle.js",
5455

5556
"src/system/Canvas.js",
5657
"src/system/Device.js",

0 commit comments

Comments
 (0)