phaser/src/gameobjects/particles/Particle.js

783 lines
22 KiB
JavaScript
Raw Normal View History

2018-02-12 16:01:20 +00:00
/**
* @author Richard Davey <rich@photonstorm.com>
2023-01-02 17:36:27 +00:00
* @copyright 2013-2023 Photon Storm Ltd.
2019-05-10 15:15:04 +00:00
* @license {@link https://opensource.org/licenses/MIT|MIT License}
2018-02-12 16:01:20 +00:00
*/
2022-12-13 18:51:15 +00:00
var AnimationState = require('../../animations/AnimationState');
2017-10-17 03:16:08 +00:00
var Class = require('../../utils/Class');
var DegToRad = require('../../math/DegToRad');
2023-01-03 13:14:29 +00:00
var Rectangle = require('../../geom/rectangle/Rectangle');
var RotateAround = require('../../math/RotateAround');
var Vector2 = require('../../math/Vector2');
2017-10-17 03:16:08 +00:00
2018-02-06 22:25:23 +00:00
/**
2018-02-07 15:27:21 +00:00
* @classdesc
2018-04-18 15:32:03 +00:00
* A Particle is a simple Game Object controlled by a Particle Emitter and Manager, and rendered by the Manager.
* It uses its own lightweight physics system, and can interact only with its Emitter's bounds and zones.
2018-02-06 22:25:23 +00:00
*
* @class Particle
2018-10-10 09:49:13 +00:00
* @memberof Phaser.GameObjects.Particles
2018-02-06 22:25:23 +00:00
* @constructor
* @since 3.0.0
*
* @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter to which this Particle belongs.
*/
2017-10-17 03:16:08 +00:00
var Particle = new Class({
initialize:
function Particle (emitter)
2017-10-17 03:16:08 +00:00
{
2018-02-06 22:25:23 +00:00
/**
* The Emitter to which this Particle belongs.
*
* A Particle can only belong to a single Emitter and is created, updated and destroyed via it.
*
* @name Phaser.GameObjects.Particles.Particle#emitter
* @type {Phaser.GameObjects.Particles.ParticleEmitter}
* @since 3.0.0
*/
this.emitter = emitter;
2022-12-13 18:51:15 +00:00
/**
* The texture used to render this Particle.
*
* @name Phaser.GameObjects.Particles.Particle#texture
* @type {Phaser.Textures.Texture}
* @default null
* @since 3.60.0
*/
this.texture = null;
2018-02-06 22:25:23 +00:00
/**
2018-04-18 15:32:03 +00:00
* The texture frame used to render this Particle.
2018-02-06 22:25:23 +00:00
*
* @name Phaser.GameObjects.Particles.Particle#frame
2018-03-28 14:04:09 +00:00
* @type {Phaser.Textures.Frame}
2018-02-06 22:25:23 +00:00
* @default null
* @since 3.0.0
*/
2017-10-18 14:18:42 +00:00
this.frame = null;
2017-10-17 03:16:08 +00:00
2018-02-06 22:25:23 +00:00
/**
* The x coordinate of this Particle.
*
* @name Phaser.GameObjects.Particles.Particle#x
* @type {number}
* @default 0
* @since 3.0.0
*/
2017-10-18 14:18:42 +00:00
this.x = 0;
2018-02-06 22:25:23 +00:00
/**
* The y coordinate of this Particle.
*
* @name Phaser.GameObjects.Particles.Particle#y
* @type {number}
* @default 0
* @since 3.0.0
*/
2017-10-18 14:18:42 +00:00
this.y = 0;
2017-10-17 03:16:08 +00:00
2018-02-06 22:25:23 +00:00
/**
* The x velocity of this Particle.
*
* @name Phaser.GameObjects.Particles.Particle#velocityX
* @type {number}
* @default 0
* @since 3.0.0
*/
2017-10-17 03:16:08 +00:00
this.velocityX = 0;
2018-02-06 22:25:23 +00:00
/**
* The y velocity of this Particle.
*
* @name Phaser.GameObjects.Particles.Particle#velocityY
* @type {number}
* @default 0
* @since 3.0.0
*/
2017-10-17 03:16:08 +00:00
this.velocityY = 0;
2018-02-06 22:25:23 +00:00
/**
* The x acceleration of this Particle.
*
* @name Phaser.GameObjects.Particles.Particle#accelerationX
* @type {number}
* @default 0
* @since 3.0.0
*/
this.accelerationX = 0;
2018-02-06 22:25:23 +00:00
/**
* The y acceleration of this Particle.
*
* @name Phaser.GameObjects.Particles.Particle#accelerationY
* @type {number}
* @default 0
* @since 3.0.0
*/
this.accelerationY = 0;
2018-02-06 22:25:23 +00:00
/**
* The maximum horizontal velocity this Particle can travel at.
*
* @name Phaser.GameObjects.Particles.Particle#maxVelocityX
* @type {number}
* @default 10000
* @since 3.0.0
*/
this.maxVelocityX = 10000;
2018-02-06 22:25:23 +00:00
/**
* The maximum vertical velocity this Particle can travel at.
*
* @name Phaser.GameObjects.Particles.Particle#maxVelocityY
* @type {number}
* @default 10000
* @since 3.0.0
*/
this.maxVelocityY = 10000;
2018-02-06 22:25:23 +00:00
/**
* The bounciness, or restitution, of this Particle.
*
* @name Phaser.GameObjects.Particles.Particle#bounce
* @type {number}
* @default 0
* @since 3.0.0
*/
this.bounce = 0;
2018-02-06 22:25:23 +00:00
/**
* The horizontal scale of this Particle.
*
* @name Phaser.GameObjects.Particles.Particle#scaleX
* @type {number}
2018-02-06 22:25:23 +00:00
* @default 1
* @since 3.0.0
*/
2017-10-17 03:16:08 +00:00
this.scaleX = 1;
2018-02-06 22:25:23 +00:00
/**
* The vertical scale of this Particle.
*
* @name Phaser.GameObjects.Particles.Particle#scaleY
* @type {number}
2018-02-06 22:25:23 +00:00
* @default 1
* @since 3.0.0
*/
2017-10-17 03:16:08 +00:00
this.scaleY = 1;
2018-02-06 22:25:23 +00:00
/**
* The alpha value of this Particle.
*
* @name Phaser.GameObjects.Particles.Particle#alpha
* @type {number}
2018-02-06 22:25:23 +00:00
* @default 1
* @since 3.0.0
*/
2017-10-18 01:26:15 +00:00
this.alpha = 1;
2018-02-06 22:25:23 +00:00
/**
* The angle of this Particle in degrees.
*
* @name Phaser.GameObjects.Particles.Particle#angle
* @type {number}
* @default 0
* @since 3.0.0
*/
this.angle = 0;
2018-02-06 22:25:23 +00:00
/**
* The angle of this Particle in radians.
*
* @name Phaser.GameObjects.Particles.Particle#rotation
* @type {number}
* @default 0
* @since 3.0.0
*/
2017-10-17 03:16:08 +00:00
this.rotation = 0;
2018-02-06 22:25:23 +00:00
/**
* The tint applied to this Particle.
*
* @name Phaser.GameObjects.Particles.Particle#tint
2020-11-23 10:22:13 +00:00
* @type {number}
2018-02-06 22:25:23 +00:00
* @webglOnly
* @since 3.0.0
*/
this.tint = 0xffffff;
2018-02-06 22:25:23 +00:00
/**
* The lifespan of this Particle in ms.
*
* @name Phaser.GameObjects.Particles.Particle#life
* @type {number}
* @default 1000
* @since 3.0.0
*/
2017-10-18 01:26:15 +00:00
this.life = 1000;
2018-02-06 22:25:23 +00:00
/**
* The current life of this Particle in ms.
*
* @name Phaser.GameObjects.Particles.Particle#lifeCurrent
* @type {number}
* @default 1000
* @since 3.0.0
*/
2017-10-18 01:26:15 +00:00
this.lifeCurrent = 1000;
2018-02-06 22:25:23 +00:00
/**
* The delay applied to this Particle upon emission, in ms.
*
* @name Phaser.GameObjects.Particles.Particle#delayCurrent
* @type {number}
* @default 0
* @since 3.0.0
*/
2017-10-27 11:31:37 +00:00
this.delayCurrent = 0;
2017-10-17 03:16:08 +00:00
2018-02-06 22:25:23 +00:00
/**
2018-04-18 15:32:03 +00:00
* The normalized lifespan T value, where 0 is the start and 1 is the end.
2018-02-06 22:25:23 +00:00
*
* @name Phaser.GameObjects.Particles.Particle#lifeT
* @type {number}
2018-02-06 22:25:23 +00:00
* @default 0
* @since 3.0.0
*/
this.lifeT = 0;
2018-02-06 22:25:23 +00:00
/**
* The data used by the ease equation.
*
* @name Phaser.GameObjects.Particles.Particle#data
* @type {object}
* @since 3.0.0
*/
2017-10-18 01:26:15 +00:00
this.data = {
2022-12-18 17:22:39 +00:00
tint: { min: 0xffffff, max: 0xffffff },
alpha: { min: 1, max: 1 },
2017-10-24 02:31:54 +00:00
rotate: { min: 0, max: 0 },
scaleX: { min: 1, max: 1 },
2022-12-15 13:33:58 +00:00
scaleY: { min: 1, max: 1 },
x: { min: 0, max: 0 },
y: { min: 0, max: 0 },
accelerationX: { min: 0, max: 0 },
accelerationY: { min: 0, max: 0 },
maxVelocityX: { min: 0, max: 0 },
maxVelocityY: { min: 0, max: 0 },
moveToX: { min: 0, max: 0 },
moveToY: { min: 0, max: 0 },
bounce: { min: 0, max: 0 }
2017-10-17 03:16:08 +00:00
};
2022-12-13 18:51:15 +00:00
/**
* Interal private value.
*
* @name Phaser.GameObjects.Particles.Particle#isCropped
* @type {boolean}
* @private
* @readonly
* @since 3.60.0
*/
2022-12-13 18:51:15 +00:00
this.isCropped = false;
/**
* A reference to the Scene to which this Game Object belongs.
*
* Game Objects can only belong to one Scene.
*
* You should consider this property as being read-only. You cannot move a
* Game Object to another Scene by simply changing it.
*
* @name Phaser.GameObjects.Particles.Particle#scene
* @type {Phaser.Scene}
* @since 3.60.0
*/
2022-12-13 18:51:15 +00:00
this.scene = emitter.manager.scene;
/**
* The Animation State component of this Particle.
2022-12-13 18:51:15 +00:00
*
* This component provides features to apply animations to this Particle.
2022-12-13 18:51:15 +00:00
* It is responsible for playing, loading, queuing animations for later playback,
* mixing between animations and setting the current animation frame to this Particle.
2022-12-13 18:51:15 +00:00
*
* @name Phaser.GameObjects.Particles.Particle#anims
2022-12-13 18:51:15 +00:00
* @type {Phaser.Animations.AnimationState}
* @since 3.60.0
2022-12-13 18:51:15 +00:00
*/
this.anims = new AnimationState(this);
2023-01-03 13:14:29 +00:00
/**
* A rectangle that holds the bounds of this Particle after a call to
* the `Particle.getBounds` method has been made.
2023-01-03 13:14:29 +00:00
*
* @name Phaser.GameObjects.Particles.Particle#bounds
* @type {Phaser.Geom.Rectangle}
2023-01-03 13:14:29 +00:00
* @since 3.60.0
*/
this.bounds = new Rectangle();
2022-12-13 18:51:15 +00:00
},
/**
* The Event Emitter proxy.
*
* Passes on all parameters to the `ParticleEmitterManager` to emit directly.
*
* @method Phaser.GameObjects.Particles.Particle#emit
* @since 3.60.0
*
* @param {(string|Symbol)} event - The event name.
* @param {any} [a1] - Optional argument 1.
* @param {any} [a2] - Optional argument 2.
* @param {any} [a3] - Optional argument 3.
* @param {any} [a4] - Optional argument 4.
* @param {any} [a5] - Optional argument 5.
*
* @return {boolean} `true` if the event had listeners, else `false`.
*/
2022-12-13 18:51:15 +00:00
emit: function (event, a1, a2, a3, a4, a5)
{
return this.emitter.manager.emit(event, a1, a2, a3, a4, a5);
2017-10-17 03:16:08 +00:00
},
2018-02-06 22:25:23 +00:00
/**
* Checks to see if this Particle is alive and updating.
*
* @method Phaser.GameObjects.Particles.Particle#isAlive
* @since 3.0.0
*
* @return {boolean} `true` if this Particle is alive and updating, otherwise `false`.
*/
2017-10-17 03:16:08 +00:00
isAlive: function ()
{
2017-10-18 01:26:15 +00:00
return (this.lifeCurrent > 0);
2017-10-17 03:16:08 +00:00
},
/**
* Kills this particle. This sets the `lifeCurrent` value to 0, which forces
* the Particle to be removed the next time its parent Emitter runs an update.
*
* @method Phaser.GameObjects.Particles.Particle#kill
* @since 3.60.0
*/
kill: function ()
{
this.lifeCurrent = 0;
},
/**
* Sets the position of this particle to the given x/y coordinates.
*
* If the parameters are left undefined, it resets the particle back to 0x0.
*
* @method Phaser.GameObjects.Particles.Particle#setPosition
* @since 3.60.0
*
* @param {number} [x=0] - The x coordinate to set this Particle to.
* @param {number} [y=0] - The y coordinate to set this Particle to.
*/
setPosition: function (x, y)
{
if (x === undefined) { x = 0; }
if (y === undefined) { y = 0; }
this.x = x;
this.y = y;
},
2018-02-06 22:25:23 +00:00
/**
* Starts this Particle from the given coordinates.
*
* @method Phaser.GameObjects.Particles.Particle#fire
* @since 3.0.0
*
2022-12-23 17:28:56 +00:00
* @param {number} [x] - The x coordinate to launch this Particle from.
* @param {number} [y] - The y coordinate to launch this Particle from.
2018-02-06 22:25:23 +00:00
*/
fire: function (x, y)
2017-10-17 03:16:08 +00:00
{
var emitter = this.emitter;
2022-12-15 00:51:22 +00:00
var ops = emitter.ops;
var anim = emitter.getAnim();
if (anim)
{
this.anims.play(anim);
}
else
{
this.frame = emitter.getFrame();
this.texture = this.frame.texture;
}
2017-10-18 01:26:15 +00:00
if (!this.frame)
{
throw new Error('Particle has no texture frame');
}
// Updates particle.x and particle.y during this call
emitter.getEmitZone(this);
2017-10-18 01:26:15 +00:00
if (x === undefined)
{
2022-12-15 00:51:22 +00:00
this.x += ops.x.onEmit(this, 'x');
}
2022-12-15 00:51:22 +00:00
else if (ops.x.steps > 0)
{
// EmitterOp is stepped but x was forced (follower?) so use it
2022-12-15 00:51:22 +00:00
this.x += x + ops.x.onEmit(this, 'x');
}
else
{
this.x += x;
}
if (y === undefined)
{
2022-12-15 00:51:22 +00:00
this.y += ops.y.onEmit(this, 'y');
}
2022-12-15 00:51:22 +00:00
else if (ops.y.steps > 0)
{
// EmitterOp is stepped but y was forced (follower?) so use it
2022-12-15 00:51:22 +00:00
this.y += y + ops.y.onEmit(this, 'y');
}
else
{
this.y += y;
}
2017-10-18 01:26:15 +00:00
2022-12-15 00:51:22 +00:00
this.life = ops.lifespan.onEmit(this, 'lifespan');
2017-10-27 20:19:30 +00:00
this.lifeCurrent = this.life;
this.lifeT = 0;
2022-12-15 00:51:22 +00:00
var sx = ops.speedX.onEmit(this, 'speedX');
var sy = (ops.speedY.active) ? ops.speedY.onEmit(this, 'speedY') : sx;
2017-10-18 14:18:42 +00:00
if (emitter.radial)
2017-10-18 01:26:15 +00:00
{
2022-12-15 00:51:22 +00:00
var rad = DegToRad(ops.angle.onEmit(this, 'angle'));
2017-10-18 14:18:42 +00:00
this.velocityX = Math.cos(rad) * Math.abs(sx);
this.velocityY = Math.sin(rad) * Math.abs(sy);
}
2017-10-27 20:19:30 +00:00
else if (emitter.moveTo)
{
2022-12-15 00:51:22 +00:00
var mx = ops.moveToX.onEmit(this, 'moveToX');
var my = ops.moveToY.onEmit(this, 'moveToY');
2022-03-25 18:24:59 +00:00
var lifeS = this.life / 1000;
2017-10-27 20:19:30 +00:00
2022-03-25 18:24:59 +00:00
this.velocityX = (mx - this.x) / lifeS;
this.velocityY = (my - this.y) / lifeS;
2017-10-27 20:19:30 +00:00
}
2017-10-18 14:18:42 +00:00
else
{
this.velocityX = sx;
this.velocityY = sy;
2017-10-18 01:26:15 +00:00
}
if (emitter.acceleration)
{
2022-12-15 00:51:22 +00:00
this.accelerationX = ops.accelerationX.onEmit(this, 'accelerationX');
this.accelerationY = ops.accelerationY.onEmit(this, 'accelerationY');
}
2022-12-15 00:51:22 +00:00
this.maxVelocityX = ops.maxVelocityX.onEmit(this, 'maxVelocityX');
this.maxVelocityY = ops.maxVelocityY.onEmit(this, 'maxVelocityY');
2022-12-15 00:51:22 +00:00
this.delayCurrent = ops.delay.onEmit(this, 'delay');
2017-10-27 11:31:37 +00:00
2022-12-15 00:51:22 +00:00
this.scaleX = ops.scaleX.onEmit(this, 'scaleX');
this.scaleY = (ops.scaleY.active) ? ops.scaleY.onEmit(this, 'scaleY') : this.scaleX;
2022-12-15 00:51:22 +00:00
this.angle = ops.rotate.onEmit(this, 'rotate');
this.rotation = DegToRad(this.angle);
2022-12-15 00:51:22 +00:00
this.bounce = ops.bounce.onEmit(this, 'bounce');
2022-12-15 00:51:22 +00:00
this.alpha = ops.alpha.onEmit(this, 'alpha');
2022-12-15 00:51:22 +00:00
this.tint = ops.tint.onEmit(this, 'tint');
2017-10-17 03:16:08 +00:00
},
2018-02-06 22:25:23 +00:00
/**
* An internal method that calculates the velocity of the Particle.
*
* @method Phaser.GameObjects.Particles.Particle#computeVelocity
* @since 3.0.0
*
* @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter that is updating this Particle.
* @param {number} delta - The delta time in ms.
* @param {number} step - The delta value divided by 1000.
2018-04-18 15:32:03 +00:00
* @param {array} processors - Particle processors (gravity wells).
2018-02-06 22:25:23 +00:00
*/
2022-12-15 13:33:58 +00:00
computeVelocity: function (emitter, delta, step, processors, t)
{
2022-12-15 13:33:58 +00:00
var ops = emitter.ops;
var vx = this.velocityX;
var vy = this.velocityY;
2022-12-15 13:33:58 +00:00
var ax = ops.accelerationX.onUpdate(this, 'accelerationX', t, this.accelerationX);
var ay = ops.accelerationY.onUpdate(this, 'accelerationY', t, this.accelerationY);
2022-12-15 13:33:58 +00:00
var mx = ops.maxVelocityX.onUpdate(this, 'maxVelocityX', t, this.maxVelocityX);
var my = ops.maxVelocityY.onUpdate(this, 'maxVelocityY', t, this.maxVelocityY);
vx += (emitter.gravityX * step);
vy += (emitter.gravityY * step);
if (ax)
{
vx += (ax * step);
}
if (ay)
{
vy += (ay * step);
}
if (vx > mx)
{
vx = mx;
}
else if (vx < -mx)
{
vx = -mx;
}
if (vy > my)
{
vy = my;
}
else if (vy < -my)
{
vy = -my;
}
this.velocityX = vx;
this.velocityY = vy;
// Apply any additional processors
for (var i = 0; i < processors.length; i++)
{
processors[i].update(this, delta, step);
}
},
2018-02-06 22:25:23 +00:00
/**
* Checks if this Particle is still within the bounds defined by the given Emitter.
*
* If not, and depending on the Emitter collision flags, the Particle may either stop or rebound.
*
* @method Phaser.GameObjects.Particles.Particle#checkBounds
* @since 3.0.0
*
* @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter to check the bounds against.
*/
checkBounds: function (emitter)
{
var bounds = emitter.bounds;
var bounce = -this.bounce;
if (this.x < bounds.x && emitter.collideLeft)
{
this.x = bounds.x;
this.velocityX *= bounce;
}
else if (this.x > bounds.right && emitter.collideRight)
{
this.x = bounds.right;
this.velocityX *= bounce;
}
if (this.y < bounds.y && emitter.collideTop)
{
this.y = bounds.y;
this.velocityY *= bounce;
}
else if (this.y > bounds.bottom && emitter.collideBottom)
{
this.y = bounds.bottom;
this.velocityY *= bounce;
}
},
2018-02-06 22:25:23 +00:00
/**
* The main update method for this Particle.
*
* Updates its life values, computes the velocity and repositions the Particle.
*
* @method Phaser.GameObjects.Particles.Particle#update
* @since 3.0.0
*
* @param {number} delta - The delta time in ms.
* @param {number} step - The delta value divided by 1000.
2018-02-06 22:25:23 +00:00
* @param {array} processors - An optional array of update processors.
*
* @return {boolean} Returns `true` if this Particle has now expired and should be removed, otherwise `false` if still active.
*/
update: function (delta, step, processors)
2017-10-17 03:16:08 +00:00
{
2017-10-27 11:31:37 +00:00
if (this.delayCurrent > 0)
{
this.delayCurrent -= delta;
2017-10-27 11:31:37 +00:00
return false;
}
if (this.lifeCurrent === 0)
{
// Particle is dead via `Particle.kill` method.
return true;
}
2022-12-13 18:51:15 +00:00
this.anims.update(0, delta);
var emitter = this.emitter;
2022-12-15 00:51:22 +00:00
var ops = emitter.ops;
2017-10-18 01:26:15 +00:00
// How far along in life is this particle? (t = 0 to 1)
var t = 1 - (this.lifeCurrent / this.life);
this.lifeT = t;
this.x = ops.x.onUpdate(this, 'x', t, this.x);
this.y = ops.y.onUpdate(this, 'y', t, this.y);
2022-12-15 13:33:58 +00:00
if (emitter.moveTo)
{
var mx = ops.moveToX.onUpdate(this, 'moveToX', t, emitter.moveToX);
var my = ops.moveToY.onUpdate(this, 'moveToY', t, emitter.moveToY);
var lifeS = this.lifeCurrent / 1000;
this.velocityX = (mx - this.x) / lifeS;
this.velocityY = (my - this.y) / lifeS;
}
this.computeVelocity(emitter, delta, step, processors, t);
this.x += this.velocityX * step;
this.y += this.velocityY * step;
if (emitter.bounds)
{
this.checkBounds(emitter);
}
if (emitter.getDeathZone(this))
{
this.lifeCurrent = 0;
// No need to go any further, particle has been killed
return true;
}
2022-12-15 00:51:22 +00:00
this.scaleX = ops.scaleX.onUpdate(this, 'scaleX', t, this.scaleX);
this.scaleY = ops.scaleY.onUpdate(this, 'scaleY', t, this.scaleY);
2022-12-15 00:51:22 +00:00
this.angle = ops.rotate.onUpdate(this, 'rotate', t, this.angle);
this.rotation = DegToRad(this.angle);
2017-10-18 01:26:15 +00:00
2022-12-15 00:51:22 +00:00
this.alpha = ops.alpha.onUpdate(this, 'alpha', t, this.alpha);
2017-10-18 01:26:15 +00:00
2022-12-19 18:35:40 +00:00
this.tint = ops.tint.onUpdate(this, 'tint', t, this.tint);
2017-10-27 20:19:30 +00:00
this.bounce = ops.bounce.onUpdate(this, 'bounce', t, this.bounce);
2017-10-18 01:26:15 +00:00
this.lifeCurrent -= delta;
2017-10-18 01:26:15 +00:00
return (this.lifeCurrent <= 0);
2022-12-13 18:51:15 +00:00
},
/**
* This is a NOOP method and does nothing when called.
*
* @method Phaser.GameObjects.Particles.Particle#setSizeToFrame
* @since 3.60.0
*/
2022-12-13 18:51:15 +00:00
setSizeToFrame: function ()
{
// NOOP
},
2023-01-03 13:14:29 +00:00
/**
* Gets the bounds of this particle as a Geometry Rectangle, factoring in any
* transforms of the parent emitter and anything else above it in the display list.
*
* Once calculated the bounds can be accessed via the `Particle.bounds` property.
2023-01-03 13:14:29 +00:00
*
* @method Phaser.GameObjects.Particles.Particle#getBounds
2023-01-03 13:14:29 +00:00
* @since 3.60.0
*
* @param {Phaser.GameObjects.Components.TransformMatrix} [matrix] - Optional transform matrix to apply to this particle.
*
* @return {Phaser.Geom.Rectangle} A Rectangle containing the transformed bounds of this particle.
2023-01-03 13:14:29 +00:00
*/
getBounds: function (matrix)
2023-01-03 13:14:29 +00:00
{
if (matrix === undefined) { matrix = this.emitter.getWorldTransformMatrix(); }
2023-01-03 13:14:29 +00:00
var sx = Math.abs(matrix.scaleX) * this.scaleX;
var sy = Math.abs(matrix.scaleY) * this.scaleY;
var x = this.x;
var y = this.y;
var rotation = this.rotation;
var width = (this.frame.width * sx) / 2;
var height = (this.frame.height * sy) / 2;
2023-01-03 13:14:29 +00:00
var bounds = this.bounds;
var topLeft = new Vector2(x - width, y - height);
var topRight = new Vector2(x + width, y - height);
var bottomLeft = new Vector2(x - width, y + height);
var bottomRight = new Vector2(x + width, y + height);
if (rotation !== 0)
{
RotateAround(topLeft, x, y, rotation);
RotateAround(topRight, x, y, rotation);
RotateAround(bottomLeft, x, y, rotation);
RotateAround(bottomRight, x, y, rotation);
}
matrix.transformPoint(topLeft.x, topLeft.y, topLeft);
matrix.transformPoint(topRight.x, topRight.y, topRight);
matrix.transformPoint(bottomLeft.x, bottomLeft.y, bottomLeft);
matrix.transformPoint(bottomRight.x, bottomRight.y, bottomRight);
bounds.x = Math.min(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
bounds.y = Math.min(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
bounds.width = Math.max(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x) - bounds.x;
bounds.height = Math.max(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y) - bounds.y;
2023-01-03 13:14:29 +00:00
return bounds;
},
/**
* Destroys this Particle.
*
* @method Phaser.GameObjects.Particles.Particle#destroy
* @since 3.60.0
*/
destroy: function ()
{
this.anims.destroy();
this.anims = null;
this.emitter = null;
this.texture = null;
this.frame = null;
this.scene = null;
2017-10-17 03:16:08 +00:00
}
});
module.exports = Particle;