pixi-particles-engine 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/behaviours/rotation-curve-behaviour.d.ts +21 -0
- package/dist/cjs/behaviours/rotation-curve-behaviour.d.ts.map +1 -0
- package/dist/cjs/behaviours/rotation-curve-behaviour.js +26 -0
- package/dist/cjs/behaviours/rotation-curve-behaviour.js.map +1 -0
- package/dist/cjs/behaviours/spawn-behaviours/circle-spawn-behaviour.d.ts +12 -5
- package/dist/cjs/behaviours/spawn-behaviours/circle-spawn-behaviour.d.ts.map +1 -1
- package/dist/cjs/behaviours/spawn-behaviours/circle-spawn-behaviour.js +15 -5
- package/dist/cjs/behaviours/spawn-behaviours/circle-spawn-behaviour.js.map +1 -1
- package/dist/cjs/behaviours/spawn-behaviours/rectangle-spawn-behaviour.d.ts +15 -5
- package/dist/cjs/behaviours/spawn-behaviours/rectangle-spawn-behaviour.d.ts.map +1 -1
- package/dist/cjs/behaviours/spawn-behaviours/rectangle-spawn-behaviour.js +36 -7
- package/dist/cjs/behaviours/spawn-behaviours/rectangle-spawn-behaviour.js.map +1 -1
- package/dist/cjs/behaviours/static-behaviours/static-rotation-behaviour.d.ts +41 -3
- package/dist/cjs/behaviours/static-behaviours/static-rotation-behaviour.d.ts.map +1 -1
- package/dist/cjs/behaviours/static-behaviours/static-rotation-behaviour.js +46 -5
- package/dist/cjs/behaviours/static-behaviours/static-rotation-behaviour.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/px-particle.d.ts +7 -2
- package/dist/cjs/px-particle.d.ts.map +1 -1
- package/dist/cjs/px-particle.js +17 -4
- package/dist/cjs/px-particle.js.map +1 -1
- package/dist/esm/behaviours/rotation-curve-behaviour.d.ts +21 -0
- package/dist/esm/behaviours/rotation-curve-behaviour.d.ts.map +1 -0
- package/dist/esm/behaviours/rotation-curve-behaviour.js +22 -0
- package/dist/esm/behaviours/rotation-curve-behaviour.js.map +1 -0
- package/dist/esm/behaviours/spawn-behaviours/circle-spawn-behaviour.d.ts +12 -5
- package/dist/esm/behaviours/spawn-behaviours/circle-spawn-behaviour.d.ts.map +1 -1
- package/dist/esm/behaviours/spawn-behaviours/circle-spawn-behaviour.js +15 -5
- package/dist/esm/behaviours/spawn-behaviours/circle-spawn-behaviour.js.map +1 -1
- package/dist/esm/behaviours/spawn-behaviours/rectangle-spawn-behaviour.d.ts +15 -5
- package/dist/esm/behaviours/spawn-behaviours/rectangle-spawn-behaviour.d.ts.map +1 -1
- package/dist/esm/behaviours/spawn-behaviours/rectangle-spawn-behaviour.js +36 -7
- package/dist/esm/behaviours/spawn-behaviours/rectangle-spawn-behaviour.js.map +1 -1
- package/dist/esm/behaviours/static-behaviours/static-rotation-behaviour.d.ts +41 -3
- package/dist/esm/behaviours/static-behaviours/static-rotation-behaviour.d.ts.map +1 -1
- package/dist/esm/behaviours/static-behaviours/static-rotation-behaviour.js +46 -5
- package/dist/esm/behaviours/static-behaviours/static-rotation-behaviour.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/px-particle.d.ts +7 -2
- package/dist/esm/px-particle.d.ts.map +1 -1
- package/dist/esm/px-particle.js +17 -4
- package/dist/esm/px-particle.js.map +1 -1
- package/package.json +2 -1
- package/src/behaviour.ts +74 -0
- package/src/behaviours/alpha-behaviour.ts +29 -0
- package/src/behaviours/alpha-curve-behaviour.ts +34 -0
- package/src/behaviours/curved-behaviour/curve-key-frame.ts +23 -0
- package/src/behaviours/curved-behaviour/curve-sampler.ts +92 -0
- package/src/behaviours/movement-behaviours/gravity-behaviour.ts +48 -0
- package/src/behaviours/movement-behaviours/movement-curve-behaviour.ts +39 -0
- package/src/behaviours/movement-behaviours/radial-burst-behaviour.ts +57 -0
- package/src/behaviours/rotation-curve-behaviour.ts +32 -0
- package/src/behaviours/scale-curve-behaviour.ts +36 -0
- package/src/behaviours/spawn-behaviours/circle-spawn-behaviour.ts +37 -0
- package/src/behaviours/spawn-behaviours/rectangle-spawn-behaviour.ts +60 -0
- package/src/behaviours/static-behaviours/static-rotation-behaviour.ts +99 -0
- package/src/behaviours/static-behaviours/static-scale-behaviour.ts +21 -0
- package/src/emitter.ts +517 -0
- package/src/index.ts +19 -0
- package/src/px-particle.ts +125 -0
- package/src/texture-provider.ts +66 -0
- package/src/texture-providers/animated-texture-provider.ts +146 -0
- package/src/texture-providers/single-texture-provider.ts +22 -0
- package/src/texture-providers/weighted-texture-provider.ts +52 -0
- package/src/utils.ts +13 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { PxParticle } from "../../px-particle";
|
|
2
|
+
import { Behaviour } from "../../behaviour";
|
|
3
|
+
import { CurveKeyframe, CurveOptions } from "../curved-behaviour/curve-key-frame";
|
|
4
|
+
import { Curve } from "../curved-behaviour/curve-sampler";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Applies an acceleration (gx, gy) scaled by a curve over lifetime.
|
|
8
|
+
*
|
|
9
|
+
* This modifies velocity every frame:
|
|
10
|
+
* v += g * strength(t) * dt
|
|
11
|
+
*
|
|
12
|
+
* where t is normalized particle age in [0..1].
|
|
13
|
+
*
|
|
14
|
+
* Typical uses:
|
|
15
|
+
* - Gravity that ramps up/down over lifetime
|
|
16
|
+
* - Wind that fades in/out
|
|
17
|
+
* - Custom "pull" forces controlled by a curve
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
export class GravityCurveBehaviour implements Behaviour {
|
|
21
|
+
public readonly requires = { position: true };
|
|
22
|
+
public readonly priority = 0;
|
|
23
|
+
|
|
24
|
+
/** Acceleration vector (units: px/s² when strength is 1). */
|
|
25
|
+
public gx: number;
|
|
26
|
+
public gy: number;
|
|
27
|
+
|
|
28
|
+
/** Strength curve sampled by normalized lifetime. */
|
|
29
|
+
private strength: Curve;
|
|
30
|
+
|
|
31
|
+
constructor(gx: number, gy: number, strengthKeyframes: CurveKeyframe[], opts?: CurveOptions) {
|
|
32
|
+
this.gx = gx;
|
|
33
|
+
this.gy = gy;
|
|
34
|
+
this.strength = new Curve(strengthKeyframes, opts);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Called every frame for each particle.
|
|
39
|
+
* dt is in seconds.
|
|
40
|
+
*/
|
|
41
|
+
public update(p: PxParticle, dt: number) {
|
|
42
|
+
const t = p.life > 0 ? p.age / p.life : 1;
|
|
43
|
+
const s = this.strength.sample(t);
|
|
44
|
+
|
|
45
|
+
p.vx += this.gx * s * dt;
|
|
46
|
+
p.vy += this.gy * s * dt;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { PxParticle } from "../../px-particle";
|
|
2
|
+
import { Behaviour } from "../../behaviour";
|
|
3
|
+
import { CurveKeyframe, CurveOptions } from "../curved-behaviour/curve-key-frame";
|
|
4
|
+
import { Curve } from "../curved-behaviour/curve-sampler";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Drives particle velocity directly using curves over lifetime.
|
|
8
|
+
*
|
|
9
|
+
* Each frame:
|
|
10
|
+
* vx = vxCurve(t)
|
|
11
|
+
* vy = vyCurve(t)
|
|
12
|
+
*
|
|
13
|
+
* where t is normalized lifetime in [0..1].
|
|
14
|
+
*
|
|
15
|
+
* IMPORTANT:
|
|
16
|
+
* - This behaviour overwrites velocity every frame.
|
|
17
|
+
* - Forces like GravityCurveBehaviour should run AFTER this behaviour
|
|
18
|
+
* if you want gravity to modify the curve-driven motion.
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
export class MovementCurveBehaviour implements Behaviour {
|
|
22
|
+
public readonly requires = { position: true };
|
|
23
|
+
public readonly priority = -10;
|
|
24
|
+
|
|
25
|
+
private vxCurve: Curve;
|
|
26
|
+
private vyCurve: Curve;
|
|
27
|
+
|
|
28
|
+
constructor(vxKeyframes: CurveKeyframe[], vyKeyframes: CurveKeyframe[], opts?: CurveOptions) {
|
|
29
|
+
this.vxCurve = new Curve(vxKeyframes, opts);
|
|
30
|
+
this.vyCurve = new Curve(vyKeyframes, opts);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public update(p: PxParticle, dt: number) {
|
|
34
|
+
const t = p.life > 0 ? p.age / p.life : 1;
|
|
35
|
+
|
|
36
|
+
p.vx = this.vxCurve.sample(t);
|
|
37
|
+
p.vy = this.vyCurve.sample(t);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { PxParticle } from "../../px-particle";
|
|
2
|
+
import { Behaviour } from "../../behaviour";
|
|
3
|
+
import { Utils } from "../../utils";
|
|
4
|
+
import { ParticleProperties } from "pixi.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Initializes particle velocity on spawn in a radial/cone burst.
|
|
8
|
+
*
|
|
9
|
+
* - Picks a random angle within [direction - spread/2, direction + spread/2]
|
|
10
|
+
* - Picks a random speed within [minSpeed, maxSpeed]
|
|
11
|
+
* - Sets particle velocity (vx, vy) in pixels/sec
|
|
12
|
+
*
|
|
13
|
+
* Notes:
|
|
14
|
+
* - This behaviour does NOT move particles directly; the emitter integrates vx/vy each tick.
|
|
15
|
+
*/
|
|
16
|
+
export class RadialBurstBehaviour implements Behaviour {
|
|
17
|
+
public readonly priority = -80;
|
|
18
|
+
|
|
19
|
+
public requires: ParticleProperties = { position: true };
|
|
20
|
+
|
|
21
|
+
/** Minimum initial speed (px/sec). */
|
|
22
|
+
public minSpeed: number;
|
|
23
|
+
|
|
24
|
+
/** Maximum initial speed (px/sec). */
|
|
25
|
+
public maxSpeed: number;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Center direction in radians.
|
|
29
|
+
* Pixi coordinate system:
|
|
30
|
+
* - 0 = right
|
|
31
|
+
* - PI/2 = down
|
|
32
|
+
*/
|
|
33
|
+
public direction: number = 0;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Cone spread in radians.
|
|
37
|
+
* - 2π = full circle
|
|
38
|
+
* - PI/3 ≈ 60° cone
|
|
39
|
+
*/
|
|
40
|
+
public spread: number = Math.PI * 2;
|
|
41
|
+
|
|
42
|
+
constructor(minSpeed: number, maxSpeed: number, direction: number = 0, spread: number = Math.PI * 2) {
|
|
43
|
+
this.minSpeed = minSpeed;
|
|
44
|
+
this.maxSpeed = maxSpeed;
|
|
45
|
+
this.direction = direction;
|
|
46
|
+
this.spread = spread;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public onSpawn(p: PxParticle) {
|
|
50
|
+
const half = this.spread * 0.5;
|
|
51
|
+
const angle = this.direction + Utils.rand(-half, half);
|
|
52
|
+
const speed = Utils.rand(this.minSpeed, this.maxSpeed);
|
|
53
|
+
|
|
54
|
+
p.vx = Math.cos(angle) * speed;
|
|
55
|
+
p.vy = Math.sin(angle) * speed;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Behaviour } from "../behaviour";
|
|
2
|
+
import { PxParticle } from "../px-particle";
|
|
3
|
+
import { CurveKeyframe, CurveOptions } from "./curved-behaviour/curve-key-frame";
|
|
4
|
+
import { Curve } from "./curved-behaviour/curve-sampler";
|
|
5
|
+
import { Emitter } from "../emitter";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Rotation over lifetime driven by a curve.
|
|
9
|
+
*
|
|
10
|
+
* Keyframes are sampled using normalized lifetime t in [0..1].
|
|
11
|
+
* Output is clamped to [0..1].
|
|
12
|
+
*/
|
|
13
|
+
export class RotationCurveBehaviour implements Behaviour {
|
|
14
|
+
public readonly requires = { color: true };
|
|
15
|
+
|
|
16
|
+
public readonly priority = 50;
|
|
17
|
+
|
|
18
|
+
private curve: Curve;
|
|
19
|
+
|
|
20
|
+
constructor(keyframes: CurveKeyframe[], opts?: CurveOptions) {
|
|
21
|
+
this.curve = new Curve(keyframes);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public onSpawn(p: PxParticle) {
|
|
25
|
+
p.angleVScale = this.curve.sample(0);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public update(p: PxParticle, _dt?: number, _emitter?: Emitter) {
|
|
29
|
+
const t = p.life > 0 ? p.age / p.life : 1;
|
|
30
|
+
p.angleVScale = this.curve.sample(t);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { PxParticle } from "../px-particle";
|
|
2
|
+
import { Behaviour } from "../behaviour";
|
|
3
|
+
import { CurveKeyframe, CurveOptions } from "./curved-behaviour/curve-key-frame";
|
|
4
|
+
import { Curve } from "./curved-behaviour/curve-sampler";
|
|
5
|
+
import { Emitter } from "../emitter";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Uniform scale over lifetime driven by a curve.
|
|
9
|
+
*
|
|
10
|
+
* Samples a curve using normalized lifetime t in [0..1] and applies:
|
|
11
|
+
* scaleX = scaleY = curve(t)
|
|
12
|
+
*/
|
|
13
|
+
export class ScaleCurveBehaviour implements Behaviour {
|
|
14
|
+
public readonly requires = { vertex: true };
|
|
15
|
+
|
|
16
|
+
public readonly priority = 50;
|
|
17
|
+
|
|
18
|
+
private curve: Curve;
|
|
19
|
+
|
|
20
|
+
constructor(keyframes: CurveKeyframe[], opts?: CurveOptions) {
|
|
21
|
+
this.curve = new Curve(keyframes, { ...opts });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public onSpawn(p: PxParticle) {
|
|
25
|
+
const s = this.curve.sample(0);
|
|
26
|
+
p.scaleX = s;
|
|
27
|
+
p.scaleY = s;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public update(p: PxParticle, _dt?: number, _emitter?: Emitter) {
|
|
31
|
+
const t = p.life > 0 ? p.age / p.life : 1;
|
|
32
|
+
const s = this.curve.sample(t);
|
|
33
|
+
p.scaleX = s;
|
|
34
|
+
p.scaleY = s;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { PxParticle } from "../../px-particle";
|
|
2
|
+
import { Behaviour } from "../../behaviour";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Spawns particles inside a circular ring centered at (0, 0).
|
|
6
|
+
*
|
|
7
|
+
* Outer radius:
|
|
8
|
+
* radius
|
|
9
|
+
*
|
|
10
|
+
* Inner empty radius:
|
|
11
|
+
* innerRadius
|
|
12
|
+
*
|
|
13
|
+
* Particles spawn only between the outer and inner circles.
|
|
14
|
+
*
|
|
15
|
+
* Uses sqrt(random) to maintain uniform area distribution.
|
|
16
|
+
*/
|
|
17
|
+
export class CircleSpawnBehaviour implements Behaviour {
|
|
18
|
+
public readonly priority = -100;
|
|
19
|
+
|
|
20
|
+
constructor(
|
|
21
|
+
public radius: number,
|
|
22
|
+
public innerRadius: number = 0,
|
|
23
|
+
) {}
|
|
24
|
+
|
|
25
|
+
public onSpawn(p: PxParticle) {
|
|
26
|
+
const angle = Math.random() * Math.PI * 2;
|
|
27
|
+
|
|
28
|
+
const outerR2 = this.radius * this.radius;
|
|
29
|
+
const innerR2 = this.innerRadius * this.innerRadius;
|
|
30
|
+
|
|
31
|
+
// Uniform distribution across ring area
|
|
32
|
+
const r = Math.sqrt(innerR2 + Math.random() * (outerR2 - innerR2));
|
|
33
|
+
|
|
34
|
+
p.x = Math.cos(angle) * r;
|
|
35
|
+
p.y = Math.sin(angle) * r;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { PxParticle } from "../../px-particle";
|
|
2
|
+
import { Behaviour } from "../../behaviour";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Spawns particles inside a rectangular border/ring centered at (0, 0).
|
|
6
|
+
*
|
|
7
|
+
* Outer size:
|
|
8
|
+
* width x height
|
|
9
|
+
*
|
|
10
|
+
* Inner empty area:
|
|
11
|
+
* innerWidth x innerHeight
|
|
12
|
+
*
|
|
13
|
+
* Particles spawn only in the area between the outer and inner rectangles.
|
|
14
|
+
*/
|
|
15
|
+
export class RectangleSpawnBehaviour implements Behaviour {
|
|
16
|
+
public readonly priority = -100;
|
|
17
|
+
|
|
18
|
+
constructor(
|
|
19
|
+
public width: number,
|
|
20
|
+
public height: number,
|
|
21
|
+
|
|
22
|
+
// Optional inner empty rectangle
|
|
23
|
+
public innerWidth: number = 0,
|
|
24
|
+
public innerHeight: number = 0,
|
|
25
|
+
) {}
|
|
26
|
+
|
|
27
|
+
public onSpawn(p: PxParticle) {
|
|
28
|
+
const outerHW = this.width * 0.5;
|
|
29
|
+
const outerHH = this.height * 0.5;
|
|
30
|
+
|
|
31
|
+
const innerHW = this.innerWidth * 0.5;
|
|
32
|
+
const innerHH = this.innerHeight * 0.5;
|
|
33
|
+
|
|
34
|
+
// No inner hole -> normal rectangle spawn
|
|
35
|
+
if (this.innerWidth <= 0 || this.innerHeight <= 0) {
|
|
36
|
+
p.x = this.rand(-outerHW, outerHW);
|
|
37
|
+
p.y = this.rand(-outerHH, outerHH);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Pick a random point until it lands outside the inner rectangle
|
|
42
|
+
while (true) {
|
|
43
|
+
const x = this.rand(-outerHW, outerHW);
|
|
44
|
+
const y = this.rand(-outerHH, outerHH);
|
|
45
|
+
|
|
46
|
+
const insideInner = x > -innerHW && x < innerHW && y > -innerHH && y < innerHH;
|
|
47
|
+
|
|
48
|
+
if (!insideInner) {
|
|
49
|
+
p.x = x;
|
|
50
|
+
p.y = y;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Inclusive-exclusive uniform random. */
|
|
57
|
+
private rand(min: number, max: number) {
|
|
58
|
+
return min + Math.random() * (max - min);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Behaviour } from "../../behaviour";
|
|
2
|
+
import { PxParticle } from "../../px-particle";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Sets a particle's angular velocity at spawn time.
|
|
6
|
+
*
|
|
7
|
+
* Does NOT modify rotation per frame directly.
|
|
8
|
+
* Instead, it initializes `angleVBase`, which the emitter integrates each tick.
|
|
9
|
+
*
|
|
10
|
+
* Supports:
|
|
11
|
+
*
|
|
12
|
+
* - Fixed value:
|
|
13
|
+
* 2
|
|
14
|
+
*
|
|
15
|
+
* - Random range:
|
|
16
|
+
* { min: -3, max: 3 }
|
|
17
|
+
*
|
|
18
|
+
* - Random range with minimum absolute magnitude:
|
|
19
|
+
* { min: -3, max: 3, minAbs: 2 }
|
|
20
|
+
*
|
|
21
|
+
* Result:
|
|
22
|
+
* [-3 .. -2] U [2 .. 3]
|
|
23
|
+
*/
|
|
24
|
+
export class StaticRotationBehaviour implements Behaviour {
|
|
25
|
+
public readonly priority = -60;
|
|
26
|
+
|
|
27
|
+
public readonly requires = { rotation: true };
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param speed
|
|
31
|
+
* - number → fixed angular velocity
|
|
32
|
+
* - object → randomized angular velocity
|
|
33
|
+
*/
|
|
34
|
+
constructor(
|
|
35
|
+
public speed:
|
|
36
|
+
| number
|
|
37
|
+
| {
|
|
38
|
+
min: number;
|
|
39
|
+
max: number;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Optional minimum absolute value.
|
|
43
|
+
*
|
|
44
|
+
* Example:
|
|
45
|
+
* min=-3
|
|
46
|
+
* max=3
|
|
47
|
+
* minAbs=2
|
|
48
|
+
*
|
|
49
|
+
* Produces:
|
|
50
|
+
* [-3..-2] U [2..3]
|
|
51
|
+
*/
|
|
52
|
+
minAbs?: number;
|
|
53
|
+
},
|
|
54
|
+
) {}
|
|
55
|
+
|
|
56
|
+
public onSpawn(p: PxParticle) {
|
|
57
|
+
const s = typeof this.speed === "number" ? this.speed : this.randomRange(this.speed.min, this.speed.max, this.speed.minAbs);
|
|
58
|
+
|
|
59
|
+
p.angleVBase = s;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private randomRange(min: number, max: number, minAbs?: number): number {
|
|
63
|
+
// Normal range
|
|
64
|
+
if (minAbs == null || minAbs <= 0) {
|
|
65
|
+
return min + Math.random() * (max - min);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// If the excluded center does not intersect range,
|
|
69
|
+
// fallback to normal random
|
|
70
|
+
if (min >= minAbs || max <= -minAbs) {
|
|
71
|
+
return min + Math.random() * (max - min);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const leftMin = min;
|
|
75
|
+
const leftMax = Math.min(-minAbs, max);
|
|
76
|
+
|
|
77
|
+
const rightMin = Math.max(minAbs, min);
|
|
78
|
+
const rightMax = max;
|
|
79
|
+
|
|
80
|
+
const leftSize = Math.max(0, leftMax - leftMin);
|
|
81
|
+
const rightSize = Math.max(0, rightMax - rightMin);
|
|
82
|
+
|
|
83
|
+
const total = leftSize + rightSize;
|
|
84
|
+
|
|
85
|
+
if (total <= 0) {
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const pick = Math.random() * total;
|
|
90
|
+
|
|
91
|
+
// Left segment
|
|
92
|
+
if (pick < leftSize) {
|
|
93
|
+
return leftMin + Math.random() * leftSize;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Right segment
|
|
97
|
+
return rightMin + Math.random() * rightSize;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Behaviour } from "../../behaviour";
|
|
2
|
+
import { PxParticle } from "../../px-particle";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Sets particle scale at spawn time.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
export class StaticScaleBehaviour implements Behaviour {
|
|
9
|
+
public readonly priority = -60;
|
|
10
|
+
|
|
11
|
+
public spawnScale: number;
|
|
12
|
+
|
|
13
|
+
constructor(spawnScale: number) {
|
|
14
|
+
this.spawnScale = spawnScale;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public onSpawn(p: PxParticle) {
|
|
18
|
+
p.scaleX = this.spawnScale;
|
|
19
|
+
p.scaleY = this.spawnScale;
|
|
20
|
+
}
|
|
21
|
+
}
|