Files
Some_Projects/Hommie/effects3d.js

167 lines
5.4 KiB
JavaScript

/**
* Effects3D Class - Visual Effects for 3D Game
*/
class Effects3D {
constructor(scene) {
this.scene = scene;
this.particles = [];
}
// Создание системы частиц
createParticleSystem(x, y, z, color, count = 20) {
const geometry = new THREE.BufferGeometry();
const positions = [];
const velocities = [];
for (let i = 0; i < count; i++) {
positions.push(x, y, z);
velocities.push(
(Math.random() - 0.5) * 0.3,
Math.random() * 0.2,
(Math.random() - 0.5) * 0.3
);
}
geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
const material = new THREE.PointsMaterial({
color: color,
size: 0.15,
transparent: true,
opacity: 1
});
const particles = new THREE.Points(geometry, material);
this.scene.add(particles);
return {
mesh: particles,
velocities: velocities,
life: 1.0,
update: () => {
const positions = particles.geometry.attributes.position.array;
for (let i = 0; i < count; i++) {
positions[i * 3] += velocities[i * 3];
positions[i * 3 + 1] += velocities[i * 3 + 1];
positions[i * 3 + 2] += velocities[i * 3 + 2];
velocities[i * 3 + 1] -= 0.01; // гравитация
}
particles.geometry.attributes.position.needsUpdate = true;
particles.material.opacity = this.life;
this.life -= 0.02;
}
};
}
// Эффект при получении урона
showDamageEffect(x, z) {
const effect = this.createParticleSystem(x, 1, z, 0xff0000, 15);
this.particles.push(effect);
}
// Эффект при получении денег
showMoneyEffect(x, z) {
const effect = this.createParticleSystem(x, 1, z, 0xffd700, 10);
this.particles.push(effect);
}
// Эффект при лечении
showHealEffect(x, z) {
const effect = this.createParticleSystem(x, 1, z, 0x00ff00, 15);
this.particles.push(effect);
}
// Эффект при убийстве врага
showKillEffect(x, z) {
const effect = this.createParticleSystem(x, 1, z, 0xff4444, 25);
this.particles.push(effect);
}
// Обновить все частицы
update() {
for (let i = this.particles.length - 1; i >= 0; i--) {
const p = this.particles[i];
p.update();
if (p.life <= 0) {
this.scene.remove(p.mesh);
p.mesh.geometry.dispose();
p.mesh.material.dispose();
this.particles.splice(i, 1);
}
}
}
// Тряска экрана
shakeScreen(intensity = 0.5) {
const originalPos = Game.camera.position.clone();
const shake = () => {
Game.camera.position.x = originalPos.x + (Math.random() - 0.5) * intensity;
Game.camera.position.y = originalPos.y + (Math.random() - 0.5) * intensity;
};
const interval = setInterval(shake, 30);
setTimeout(() => {
clearInterval(interval);
Game.camera.position.copy(originalPos);
}, 300);
}
// Плавающий текст
createFloatingText(x, y, z, text, color = '#ffffff') {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = 256;
canvas.height = 64;
context.fillStyle = 'transparent';
context.fillRect(0, 0, canvas.width, canvas.height);
context.font = 'bold 32px Arial';
context.fillStyle = color;
context.textAlign = 'center';
context.fillText(text, 128, 40);
const texture = new THREE.CanvasTexture(canvas);
const material = new THREE.SpriteMaterial({
map: texture,
transparent: true,
opacity: 1
});
const sprite = new THREE.Sprite(material);
sprite.position.set(x, y + 2, z);
sprite.scale.set(2, 0.5, 1);
this.scene.add(sprite);
// Анимация всплывания
const animate = () => {
sprite.position.y += 0.05;
sprite.material.opacity -= 0.02;
if (sprite.material.opacity <= 0) {
this.scene.remove(sprite);
texture.dispose();
material.dispose();
return;
}
requestAnimationFrame(animate);
};
animate();
}
// Очистка всех эффектов
dispose() {
this.particles.forEach(p => {
this.scene.remove(p.mesh);
p.mesh.geometry.dispose();
p.mesh.material.dispose();
});
this.particles = [];
}
}
// Глобальный экземпляр
window.Effects = null;