Files
novafarma/EMERGENCY_SYSTEMS_RECOVERY/ParticleEnhancementsSystem.js
2026-01-16 02:43:46 +01:00

376 lines
12 KiB
JavaScript

// Particle Enhancements System - Advanced particle effects for gameplay
class ParticleEnhancementsSystem {
constructor(scene) {
this.scene = scene;
// Particle pools for efficiency
this.sparklePool = [];
this.dustPool = [];
this.particleTextures = new Set();
// Create particle textures
this.createParticleTextures();
console.log('✨ ParticleEnhancementsSystem initialized');
}
// Create procedural particle textures
createParticleTextures() {
// Sparkle particle (star-shaped)
if (!this.scene.textures.exists('sparkle')) {
const graphics = this.scene.make.graphics({ x: 0, y: 0, add: false });
graphics.fillStyle(0xffffff, 1);
graphics.fillCircle(4, 4, 4);
graphics.generateTexture('sparkle', 8, 8);
graphics.destroy();
this.particleTextures.add('sparkle');
}
// Dust particle (cloud-shaped)
if (!this.scene.textures.exists('dust')) {
const graphics = this.scene.make.graphics({ x: 0, y: 0, add: false });
graphics.fillStyle(0xdddddd, 0.6);
graphics.fillCircle(3, 3, 3);
graphics.generateTexture('dust', 6, 6);
graphics.destroy();
this.particleTextures.add('dust');
}
// Leaf particle (for harvest)
if (!this.scene.textures.exists('leaf')) {
const graphics = this.scene.make.graphics({ x: 0, y: 0, add: false });
graphics.fillStyle(0x4a9d5f, 1);
graphics.fillRect(0, 0, 4, 6);
graphics.generateTexture('leaf', 4, 6);
graphics.destroy();
this.particleTextures.add('leaf');
}
// Star particle (for special effects)
if (!this.scene.textures.exists('star')) {
const graphics = this.scene.make.graphics({ x: 0, y: 0, add: false });
graphics.fillStyle(0xffee88, 1);
// 5-pointed star
const cx = 5, cy = 5, spikes = 5, outerRadius = 5, innerRadius = 2;
let rot = Math.PI / 2 * 3;
let x = cx;
let y = cy;
const step = Math.PI / spikes;
graphics.beginPath();
graphics.moveTo(cx, cy - outerRadius);
for (let i = 0; i < spikes; i++) {
x = cx + Math.cos(rot) * outerRadius;
y = cy + Math.sin(rot) * outerRadius;
graphics.lineTo(x, y);
rot += step;
x = cx + Math.cos(rot) * innerRadius;
y = cy + Math.sin(rot) * innerRadius;
graphics.lineTo(x, y);
rot += step;
}
graphics.lineTo(cx, cy - outerRadius);
graphics.closePath();
graphics.fillPath();
graphics.generateTexture('star', 10, 10);
graphics.destroy();
this.particleTextures.add('star');
}
}
// Enhanced craft sparkles (when crafting completes)
craftSparkles(x, y, color = [0xffffff, 0xffee88, 0xffaa00]) {
const emitter = this.scene.add.particles(x, y, 'sparkle', {
speed: { min: 50, max: 150 },
angle: { min: 0, max: 360 },
scale: { start: 1, end: 0 },
tint: color,
alpha: { start: 1, end: 0 },
lifespan: 1000,
quantity: 20,
blendMode: 'ADD',
emitting: false
});
emitter.setDepth(999999);
emitter.explode(20); // Burst of 20 particles
// Auto-destroy after particles fade
this.scene.time.delayedCall(1200, () => {
emitter.destroy();
});
return emitter;
}
// Walk dust clouds (when player walks)
walkDust(x, y, direction = 'down') {
// Only spawn on grass/dirt tiles
const tileSize = 48;
const tileX = Math.floor(x / tileSize);
const tileY = Math.floor(y / tileSize);
if (this.scene.terrainSystem) {
const tile = this.scene.terrainSystem.getTile(tileX, tileY);
if (!tile || (tile.type !== 'grass' && tile.type !== 'dirt')) {
return null; // No dust on water/pavement
}
}
const emitter = this.scene.add.particles(x, y + 10, 'dust', {
speed: { min: 10, max: 30 },
angle: { min: 0, max: 360 },
scale: { start: 0.5, end: 1.5 },
alpha: { start: 0.4, end: 0 },
lifespan: 500,
quantity: 2,
frequency: 100,
blendMode: 'NORMAL',
tint: 0xccaa88, // Dusty brown
emitting: false
});
emitter.setDepth(this.scene.player ? this.scene.player.sprite.depth - 1 : 100);
emitter.explode(2); // Small puff
// Auto-destroy
this.scene.time.delayedCall(600, () => {
emitter.destroy();
});
return emitter;
}
// Harvest particle burst (when harvesting crops)
harvestBurst(x, y, cropType = 'generic') {
// Determine particle color based on crop
let particleColors = [0x4a9d5f, 0x90EE90]; // Default green
let particleTexture = 'leaf';
if (cropType === 'wheat' || cropType === 'grain') {
particleColors = [0xFFD700, 0xFFA500]; // Golden
particleTexture = 'sparkle';
} else if (cropType === 'carrot' || cropType === 'root') {
particleColors = [0xFF6B35, 0xFFA500]; // Orange
particleTexture = 'leaf';
} else if (cropType === 'berry' || cropType === 'fruit') {
particleColors = [0xFF1744, 0xFF6B9D]; // Red/Pink
particleTexture = 'sparkle';
}
const emitter = this.scene.add.particles(x, y, particleTexture, {
speed: { min: 80, max: 150 },
angle: { min: -120, max: -60 }, // Upward spray
scale: { start: 1, end: 0.3 },
tint: particleColors,
alpha: { start: 1, end: 0 },
lifespan: 800,
quantity: 15,
gravityY: 200, // Gravity pull
blendMode: 'NORMAL',
emitting: false
});
emitter.setDepth(200000);
emitter.explode(15);
// Auto-destroy
this.scene.time.delayedCall(1000, () => {
emitter.destroy();
});
// Play success sound
if (this.scene.soundManager && this.scene.soundManager.beepPickup) {
this.scene.soundManager.beepPickup();
}
return emitter;
}
// Dig/Till soil particles (when using hoe)
digParticles(x, y) {
const emitter = this.scene.add.particles(x, y, 'dust', {
speed: { min: 40, max: 80 },
angle: { min: -140, max: -40 }, // Upward
scale: { start: 0.8, end: 0.2 },
alpha: { start: 0.6, end: 0 },
tint: [0x8b6f47, 0x6b4423], // Brown soil
lifespan: 600,
quantity: 10,
gravityY: 150,
blendMode: 'NORMAL',
emitting: false
});
emitter.setDepth(200000);
emitter.explode(10);
this.scene.time.delayedCall(800, () => {
emitter.destroy();
});
return emitter;
}
// Plant seed sparkle (when planting)
plantSparkle(x, y) {
const emitter = this.scene.add.particles(x, y, 'sparkle', {
speed: { min: 20, max: 50 },
angle: { min: 0, max: 360 },
scale: { start: 0.6, end: 0 },
tint: 0x90EE90, // Light green
alpha: { start: 0.8, end: 0 },
lifespan: 500,
quantity: 8,
blendMode: 'ADD',
emitting: false
});
emitter.setDepth(200000);
emitter.explode(8);
this.scene.time.delayedCall(600, () => {
emitter.destroy();
});
return emitter;
}
// Build completion effect (when placing building)
buildComplete(x, y, width = 48, height = 48) {
// Create corner sparkles
const corners = [
{ x: x - width / 2, y: y - height / 2 }, // Top-left
{ x: x + width / 2, y: y - height / 2 }, // Top-right
{ x: x - width / 2, y: y + height / 2 }, // Bottom-left
{ x: x + width / 2, y: y + height / 2 } // Bottom-right
];
corners.forEach((corner, index) => {
this.scene.time.delayedCall(index * 100, () => {
this.craftSparkles(corner.x, corner.y, [0xFFD700, 0xFFA500]);
});
});
// Center burst
this.scene.time.delayedCall(400, () => {
this.craftSparkles(x, y, [0xffffff, 0xFFD700]);
});
}
// Level up / achievement effect
levelUpEffect(x, y) {
// Ring explosion
const emitter = this.scene.add.particles(x, y, 'star', {
speed: { min: 100, max: 200 },
angle: { min: 0, max: 360 },
scale: { start: 1.5, end: 0 },
tint: [0xFFD700, 0xFFEE88, 0xFFFFFF],
alpha: { start: 1, end: 0 },
lifespan: 1500,
quantity: 30,
blendMode: 'ADD',
emitting: false
});
emitter.setDepth(999999);
emitter.explode(30);
// Upward rising stars
const rising = this.scene.add.particles(x, y, 'star', {
speedY: { min: -100, max: -50 },
speedX: { min: -20, max: 20 },
scale: { start: 0.8, end: 0 },
tint: 0xFFD700,
alpha: { start: 1, end: 0 },
lifespan: 2000,
quantity: 1,
frequency: 100,
blendMode: 'ADD'
});
rising.setDepth(999999);
// Stop after 2 seconds
this.scene.time.delayedCall(2000, () => {
rising.stop();
});
// Cleanup
this.scene.time.delayedCall(3500, () => {
emitter.destroy();
rising.destroy();
});
return { burst: emitter, rising };
}
// Damage impact effect (when hit)
damageImpact(x, y, color = 0xFF0000) {
const emitter = this.scene.add.particles(x, y, 'sparkle', {
speed: { min: 50, max: 100 },
angle: { min: 0, max: 360 },
scale: { start: 0.8, end: 0 },
tint: color,
alpha: { start: 1, end: 0 },
lifespan: 400,
quantity: 12,
blendMode: 'ADD',
emitting: false
});
emitter.setDepth(999999);
emitter.explode(12);
this.scene.time.delayedCall(500, () => {
emitter.destroy();
});
return emitter;
}
// Heal/Restore effect
healEffect(x, y) {
const emitter = this.scene.add.particles(x, y, 'sparkle', {
speedY: { min: -80, max: -40 },
speedX: { min: -20, max: 20 },
scale: { start: 0.6, end: 0 },
tint: [0x00FF00, 0x90EE90, 0xFFFFFF],
alpha: { start: 1, end: 0 },
lifespan: 1000,
quantity: 1,
frequency: 80,
blendMode: 'ADD'
});
emitter.setDepth(999999);
this.scene.time.delayedCall(1000, () => {
emitter.stop();
});
this.scene.time.delayedCall(2000, () => {
emitter.destroy();
});
return emitter;
}
// Clean up all particles
destroy() {
// Destroy created textures
for (const textureName of this.particleTextures) {
if (this.scene.textures.exists(textureName)) {
this.scene.textures.remove(textureName);
}
}
this.particleTextures.clear();
console.log('✨ ParticleEnhancementsSystem destroyed');
}
}