| 43 | * Noise module - adds random perturbation |
| 44 | */ |
| 45 | export class NoiseModule implements IParticleModule { |
| 46 | readonly name = 'Noise'; |
| 47 | enabled = true; |
| 48 | |
| 49 | /** 位置噪声强度 | Position noise strength */ |
| 50 | positionAmount: number = 0; |
| 51 | |
| 52 | /** 速度噪声强度 | Velocity noise strength */ |
| 53 | velocityAmount: number = 0; |
| 54 | |
| 55 | /** 旋转噪声强度 | Rotation noise strength */ |
| 56 | rotationAmount: number = 0; |
| 57 | |
| 58 | /** 缩放噪声强度 | Scale noise strength */ |
| 59 | scaleAmount: number = 0; |
| 60 | |
| 61 | /** 噪声频率 | Noise frequency */ |
| 62 | frequency: number = 1; |
| 63 | |
| 64 | /** 噪声滚动速度 | Noise scroll speed */ |
| 65 | scrollSpeed: number = 1; |
| 66 | |
| 67 | private _time: number = 0; |
| 68 | |
| 69 | update(p: Particle, dt: number, _normalizedAge: number): void { |
| 70 | this._time += dt * this.scrollSpeed; |
| 71 | |
| 72 | // 基于粒子位置和时间的噪声 | Noise based on particle position and time |
| 73 | const noiseX = valueNoise2D(p.x * this.frequency + this._time, p.y * this.frequency); |
| 74 | const noiseY = valueNoise2D(p.x * this.frequency, p.y * this.frequency + this._time); |
| 75 | |
| 76 | // 位置噪声 | Position noise |
| 77 | if (this.positionAmount !== 0) { |
| 78 | p.x += noiseX * this.positionAmount * dt; |
| 79 | p.y += noiseY * this.positionAmount * dt; |
| 80 | } |
| 81 | |
| 82 | // 速度噪声 | Velocity noise |
| 83 | if (this.velocityAmount !== 0) { |
| 84 | p.vx += noiseX * this.velocityAmount * dt; |
| 85 | p.vy += noiseY * this.velocityAmount * dt; |
| 86 | } |
| 87 | |
| 88 | // 旋转噪声 | Rotation noise |
| 89 | if (this.rotationAmount !== 0) { |
| 90 | p.rotation += noiseX * this.rotationAmount * dt; |
| 91 | } |
| 92 | |
| 93 | // 缩放噪声 | Scale noise |
| 94 | if (this.scaleAmount !== 0) { |
| 95 | const scaleDelta = noiseX * this.scaleAmount * dt; |
| 96 | p.scaleX += scaleDelta; |
| 97 | p.scaleY += scaleDelta; |
| 98 | } |
| 99 | } |
| 100 | } |
nothing calls this directly
no outgoing calls
no test coverage detected