Files
novafarma/src/systems/VisualEffectsSystem.js
2025-12-08 17:17:26 +01:00

129 lines
3.2 KiB
JavaScript

/**
* 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();
}
}