/** * VISUAL EFFECTS SYSTEM * Handles juice effects: screenshake, particles, lighting */ class VisualEffectsSystem { constructor(scene) { this.scene = scene; this.camera = scene.cameras.main; this.isShaking = false; } /** * Screenshake effect * @param {number} intensity - Shake strength (default 0.005) * @param {number} duration - Duration in ms (default 300) */ screenshake(intensity = 0.005, duration = 300) { if (this.isShaking) return; this.isShaking = true; this.camera.shake(duration, intensity); this.scene.time.delayedCall(duration, () => { this.isShaking = false; }); } /** * Hit particles (sparks) */ createHitParticles(x, y, color = 0xFFFFFF) { const particles = this.scene.add.particles(x, y, 'particle_white', { speed: { min: 100, max: 200 }, angle: { min: 0, max: 360 }, scale: { start: 0.5, end: 0 }, lifespan: 300, quantity: 8, tint: color }); this.scene.time.delayedCall(500, () => { particles.destroy(); }); } /** * Explosion particles */ createExplosion(x, y, color = 0xFF4444) { const particles = this.scene.add.particles(x, y, 'particle_white', { speed: { min: 200, max: 400 }, angle: { min: 0, max: 360 }, scale: { start: 1, end: 0 }, lifespan: 600, quantity: 20, tint: color, gravityY: 300 }); this.scene.time.delayedCall(800, () => { particles.destroy(); }); } /** * Dust particles (for movement) */ createDustPuff(x, y) { const particles = this.scene.add.particles(x, y, 'particle_white', { speed: { min: 30, max: 60 }, angle: { min: 0, max: 360 }, scale: { start: 0.3, end: 0 }, lifespan: 400, quantity: 5, tint: 0xCCBBAA, alpha: { start: 0.5, end: 0 } }); this.scene.time.delayedCall(500, () => { particles.destroy(); }); } /** * Flash effect (for damage, powerups) */ flash(color = 0xFFFFFF, duration = 100) { this.camera.flash(duration, ...this.hexToRGB(color)); } /** * Fade effect */ fadeOut(duration = 1000, callback) { this.camera.fadeOut(duration, 0, 0, 0); if (callback) { this.scene.time.delayedCall(duration, callback); } } fadeIn(duration = 1000) { this.camera.fadeIn(duration, 0, 0, 0); } /** * Utility: Hex to RGB */ hexToRGB(hex) { return [ (hex >> 16) & 255, (hex >> 8) & 255, hex & 255 ]; } /** * Create simple white pixel texture for particles */ static createParticleTexture(scene) { if (scene.textures.exists('particle_white')) return; const graphics = scene.make.graphics({ x: 0, y: 0, add: false }); graphics.fillStyle(0xFFFFFF, 1); graphics.fillCircle(4, 4, 4); graphics.generateTexture('particle_white', 8, 8); graphics.destroy(); } }