XGravity/Public/ecma/Fx/DeflectionSparksFx.ecma.js

77 lines
2.6 KiB
JavaScript

"use strict";
const DeflectionSparksFx = (function(){
const DeflectionSparksFx = function(xgravity){
let sparks = [];
this.add = (cell_x, cell_y, normal_x, normal_y, intensity = 1.0) => {
const base_count = Math.floor(10 + (intensity * 25));
const count = Math.min(60, base_count);
const base_angle = Math.atan2(normal_y, normal_x);
for(let i = 0; i < count; i++){
const spread = (Math.random() - 0.5) * (Math.PI * 0.7);
const spark_angle = base_angle + spread;
const speed = (Math.random() * 12 + 6) * Math.min(2.5, intensity);
const life = (Math.random() * 0.18) + 0.08;
sparks.push({
x : cell_x,
y : cell_y,
vx : Math.cos(spark_angle) * speed,
vy : Math.sin(spark_angle) * speed,
len : (Math.random() * 0.3) + 0.15,
life : life,
max_life : life,
color : Math.random() > 0.3 ? "#fef08a" : "#f97316"
});
}
};
this.update = (delta_time) => {
for(let i = sparks.length - 1; i >= 0; i--){
const s = sparks[i];
s.life -= delta_time;
if(s.life <= 0){
sparks.splice(i, 1);
continue;
}
s.x += s.vx * delta_time;
s.y += s.vy * delta_time;
s.vx *= 0.90;
s.vy *= 0.90;
}
};
this.render = (ctx, cell_px, cx, cy) => {
for(let i = 0; i < sparks.length; i++){
const s = sparks[i];
const px = cx + (s.x * cell_px);
const py = cy + (s.y * cell_px);
const progress = Math.max(0, s.life / s.max_life);
const spd = Math.sqrt(s.vx * s.vx + s.vy * s.vy);
const dir_x = spd > 0.001 ? s.vx / spd : 0;
const dir_y = spd > 0.001 ? s.vy / spd : 0;
const tail_length_px = (s.len || 0.25) * cell_px * Math.min(2.5, spd * 0.15);
ctx.lineWidth = cell_px * 0.06;
ctx.strokeStyle = s.color;
ctx.globalAlpha = progress;
ctx.beginPath();
ctx.moveTo(px, py);
ctx.lineTo(px - (dir_x * tail_length_px), py - (dir_y * tail_length_px));
ctx.stroke();
}
};
this.reset = () => {
sparks = [];
};
};
return DeflectionSparksFx;
})();