2022-12-13 09:20:36 +01:00
|
|
|
enum ANIM_END_ACTION {
|
|
|
|
loop,
|
|
|
|
pingpong,
|
|
|
|
destroy,
|
|
|
|
}
|
|
|
|
|
|
|
|
enum PARTICLE_BLEND_MODE {
|
|
|
|
normal,
|
|
|
|
additive
|
|
|
|
}
|
|
|
|
|
2022-12-16 09:18:09 +01:00
|
|
|
function __part(_node) constructor {
|
2022-12-13 09:20:36 +01:00
|
|
|
seed = irandom(99999);
|
2022-12-16 09:18:09 +01:00
|
|
|
node = _node;
|
2022-12-13 09:20:36 +01:00
|
|
|
active = false;
|
|
|
|
surf = noone;
|
|
|
|
x = 0;
|
|
|
|
y = 0;
|
|
|
|
sx = 0;
|
|
|
|
sy = 0;
|
|
|
|
ac = 0;
|
|
|
|
g = 0;
|
|
|
|
wig = 0;
|
|
|
|
|
|
|
|
boundary_data = -1;
|
|
|
|
|
|
|
|
fx = 0;
|
|
|
|
fy = 0;
|
|
|
|
|
|
|
|
gy = 0;
|
|
|
|
|
|
|
|
scx = 1;
|
|
|
|
scy = 1;
|
|
|
|
scx_s = 1;
|
|
|
|
scy_s = 1;
|
|
|
|
|
|
|
|
rot = 0;
|
|
|
|
follow = false;
|
|
|
|
rot_s = 0;
|
|
|
|
|
|
|
|
col = -1;
|
|
|
|
alp = 1;
|
|
|
|
alp_draw = alp;
|
|
|
|
alp_fade = 0;
|
|
|
|
|
|
|
|
life = 0;
|
|
|
|
life_total = 0;
|
2022-12-16 09:18:09 +01:00
|
|
|
step_int = 0;
|
2022-12-13 09:20:36 +01:00
|
|
|
|
|
|
|
anim_speed = 1;
|
|
|
|
anim_end = ANIM_END_ACTION.loop;
|
|
|
|
|
|
|
|
function create(_surf, _x, _y, _life) {
|
|
|
|
active = true;
|
|
|
|
surf = _surf;
|
|
|
|
x = _x;
|
|
|
|
y = _y;
|
|
|
|
gy = 0;
|
|
|
|
|
|
|
|
life = _life;
|
|
|
|
life_total = life;
|
2022-12-16 09:18:09 +01:00
|
|
|
node.onPartCreate(self);
|
2022-12-13 09:20:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function setPhysic(_sx, _sy, _ac, _g, _wig) {
|
|
|
|
sx = _sx;
|
|
|
|
sy = _sy;
|
|
|
|
ac = _ac;
|
|
|
|
g = _g;
|
|
|
|
|
|
|
|
wig = _wig;
|
|
|
|
}
|
|
|
|
function setTransform(_scx, _scy, _scxs, _scys, _rot, _rots, _follow) {
|
|
|
|
scx = _scx;
|
|
|
|
scy = _scy;
|
|
|
|
scx_s = _scxs;
|
|
|
|
scy_s = _scys;
|
|
|
|
rot = _rot;
|
|
|
|
rot_s = _rots;
|
|
|
|
follow = _follow;
|
|
|
|
}
|
|
|
|
function setDraw(_col, _alp, _fade) {
|
|
|
|
col = _col;
|
|
|
|
alp = _alp;
|
|
|
|
alp_draw = _alp;
|
|
|
|
alp_fade = _fade;
|
|
|
|
}
|
|
|
|
|
|
|
|
function kill() {
|
2022-12-16 09:18:09 +01:00
|
|
|
active = false;
|
|
|
|
node.onPartDestroy(self);
|
2022-12-13 09:20:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static step = function() {
|
|
|
|
if(!active) return;
|
|
|
|
var xp = x, yp = y;
|
|
|
|
x += sx;
|
|
|
|
y += sy;
|
|
|
|
|
|
|
|
var dirr = point_direction(0, 0, sx, sy);
|
|
|
|
var diss = point_distance(0, 0, sx, sy);
|
|
|
|
if(diss > 0) {
|
|
|
|
diss += ac;
|
|
|
|
dirr += random_range(-wig, wig);
|
|
|
|
sx = lengthdir_x(diss, dirr);
|
|
|
|
sy = lengthdir_y(diss, dirr);
|
|
|
|
}
|
|
|
|
|
|
|
|
gy += g;
|
|
|
|
y += gy;
|
|
|
|
|
|
|
|
if(scx_s < 0) scx = max(scx + scx_s, 0);
|
|
|
|
else scx = scx + scx_s;
|
|
|
|
if(scy_s < 0) scy = max(scy + scy_s, 0);
|
|
|
|
else scy = scy + scy_s;
|
|
|
|
|
|
|
|
if(follow)
|
|
|
|
rot = point_direction(xp, yp, x, y);
|
|
|
|
else
|
|
|
|
rot += rot_s;
|
|
|
|
alp_draw = alp * eval_bezier_cubic(1 - life / life_total, alp_fade[0], alp_fade[1], alp_fade[2], alp_fade[3]);
|
|
|
|
|
2022-12-16 09:18:09 +01:00
|
|
|
if(step_int > 0 && safe_mod(life, step_int) == 0)
|
|
|
|
node.onPartStep(self);
|
2022-12-13 09:20:36 +01:00
|
|
|
if(life-- < 0) kill();
|
|
|
|
}
|
|
|
|
|
|
|
|
function draw(exact) {
|
|
|
|
if(!active) return;
|
|
|
|
var ss = surf;
|
|
|
|
if(is_array(surf)) {
|
|
|
|
var ind = abs(round((life_total - life) * anim_speed));
|
|
|
|
var len = array_length(surf);
|
|
|
|
|
|
|
|
switch(anim_end) {
|
|
|
|
case ANIM_END_ACTION.loop:
|
|
|
|
ss = surf[safe_mod(ind, len)];
|
|
|
|
break;
|
|
|
|
case ANIM_END_ACTION.pingpong:
|
|
|
|
var ping = safe_mod(ind, (len - 1) * 2 + 1);
|
|
|
|
ss = surf[ping >= len? (len - 1) * 2 - ping : ping];
|
|
|
|
break;
|
|
|
|
case ANIM_END_ACTION.destroy:
|
|
|
|
if(ind >= len) return;
|
|
|
|
else ss = surf[ind];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!is_surface(ss)) return;
|
|
|
|
|
|
|
|
var cc = (col == -1)? c_white : gradient_eval(col, 1 - life / life_total);
|
|
|
|
var _xx, _yy;
|
|
|
|
var s_w = surface_get_width(ss) * scx;
|
|
|
|
var s_h = surface_get_height(ss) * scy;
|
|
|
|
|
|
|
|
if(boundary_data == -1) {
|
|
|
|
var _pp = point_rotate(-s_w / 2, -s_h / 2, 0, 0, rot);
|
|
|
|
_xx = x + _pp[0];
|
|
|
|
_yy = y + _pp[1];
|
|
|
|
} else {
|
|
|
|
var ww = boundary_data[2] + boundary_data[0];
|
|
|
|
var hh = boundary_data[3] + boundary_data[1];
|
|
|
|
|
|
|
|
var cx = (boundary_data[0] + boundary_data[2]) / 2;
|
|
|
|
var cy = (boundary_data[1] + boundary_data[3]) / 2;
|
|
|
|
|
|
|
|
var _pp = point_rotate(-cx, -cy, 0, 0, rot);
|
|
|
|
|
|
|
|
_xx = x + cx + _pp[0] * scx;
|
|
|
|
_yy = y + cy + _pp[1] * scy;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(exact) {
|
|
|
|
_xx = round(_xx);
|
|
|
|
_yy = round(_yy);
|
|
|
|
}
|
|
|
|
|
|
|
|
draw_surface_ext_safe(ss, _xx, _yy, scx, scy, rot, cc, alp_draw);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getPivot() {
|
|
|
|
if(boundary_data == -1)
|
|
|
|
return [x, y];
|
|
|
|
|
|
|
|
var ww = (boundary_data[2] - boundary_data[0]) * scx;
|
|
|
|
var hh = (boundary_data[3] - boundary_data[1]) * scy;
|
|
|
|
var cx = x + boundary_data[0] + ww / 2;
|
|
|
|
var cy = y + boundary_data[1] + hh / 2;
|
|
|
|
|
|
|
|
return [cx, cy];
|
|
|
|
}
|
|
|
|
}
|