178 lines
6.4 KiB
Lua
178 lines
6.4 KiB
Lua
---@class Particles: Moveable
|
|
Particles = Moveable:extend()
|
|
|
|
--Class Methods
|
|
function Particles:init(X, Y, W, H, config)
|
|
config = config or {}
|
|
|
|
Moveable.init(self,X, Y, W, H)
|
|
|
|
self.fill = config.fill
|
|
self.padding = config.padding or 0
|
|
|
|
if config.attach then
|
|
self:set_alignment{
|
|
major = config.attach,
|
|
type = 'cm',
|
|
bond = 'Strong'
|
|
}
|
|
table.insert(self.role.major.children,self)
|
|
self.parent = self.role.major
|
|
self.T.x = self.role.major.T.x + self.padding
|
|
self.T.y = self.role.major.T.y + self.padding
|
|
if self.fill then
|
|
self.T.w = self.role.major.T.w - self.padding
|
|
self.T.h = self.role.major.T.h - self.padding
|
|
end
|
|
end
|
|
|
|
self.states.hover.can = false
|
|
self.states.click.can = false
|
|
self.states.collide.can = false
|
|
self.states.drag.can = false
|
|
self.states.release_on.can = false
|
|
|
|
self.timer = config.timer or 0.5
|
|
self.timer_type = (self.created_on_pause and 'REAL') or config.timer_type or 'REAL'
|
|
self.last_real_time = G.TIMERS[self.timer_type] - self.timer
|
|
self.last_drawn = 0
|
|
self.lifespan = config.lifespan or 1
|
|
self.fade_alpha = 0
|
|
self.speed = config.speed or 1
|
|
self.max = config.max or 1000000000000000
|
|
self.pulse_max = math.min(20, config.pulse_max or 0)
|
|
self.pulsed = 0
|
|
self.vel_variation = config.vel_variation or 1
|
|
self.particles = {}
|
|
self.scale = config.scale or 1
|
|
self.colours = config.colours or {G.C.BACKGROUND.D}
|
|
|
|
if config.initialize then
|
|
for i = 1, 60 do
|
|
self.last_real_time = self.last_real_time - 15/60
|
|
self:update(15/60)
|
|
self:move(15/60)
|
|
end
|
|
end
|
|
|
|
if getmetatable(self) == Particles then
|
|
table.insert(G.I.MOVEABLE, self)
|
|
end
|
|
end
|
|
|
|
function Particles:update(dt)
|
|
if G.SETTINGS.paused and not self.created_on_pause then self.last_real_time = G.TIMERS[self.timer_type] ; return end
|
|
local added_this_frame = 0
|
|
while G.TIMERS[self.timer_type] > self.last_real_time + self.timer and (#self.particles < self.max or self.pulsed < self.pulse_max) and added_this_frame < 20 do
|
|
self.last_real_time = self.last_real_time + self.timer
|
|
local new_offset = {
|
|
x=self.fill and (0.5-math.random())*self.T.w or 0,
|
|
y=self.fill and (0.5-math.random())*self.T.h or 0
|
|
}
|
|
if self.fill and self.T.r < 0.1 and self.T.r > -0.1 then
|
|
local newer_offset = {
|
|
x = math.sin(self.T.r)*new_offset.y + math.cos(self.T.r)*new_offset.x,
|
|
y = math.sin(self.T.r)*new_offset.x + math.cos(self.T.r)*new_offset.y,
|
|
}
|
|
new_offset = newer_offset
|
|
end
|
|
table.insert(self.particles, {
|
|
draw = false,
|
|
dir = math.random()*2*math.pi,
|
|
facing = math.random()*2*math.pi,
|
|
size = math.random()*0.5+0.1,
|
|
age = 0,
|
|
velocity = self.speed*(self.vel_variation*math.random() + (1-self.vel_variation))*0.7,
|
|
r_vel = 0.2*(0.5 - math.random()),
|
|
e_prev = 0,
|
|
e_curr = 0,
|
|
scale = 0,
|
|
visible_scale = 0,
|
|
time = G.TIMERS[self.timer_type],
|
|
colour = pseudorandom_element(self.colours),
|
|
offset = new_offset
|
|
})
|
|
added_this_frame = added_this_frame + 1
|
|
if self.pulsed <= self.pulse_max then self.pulsed = self.pulsed + 1 end
|
|
end
|
|
end
|
|
|
|
function Particles:move(dt)
|
|
if G.SETTINGS.paused and not self.created_on_pause then return end
|
|
|
|
Moveable.move(self, dt)
|
|
|
|
if self.timer_type ~= 'REAL' then dt = dt*G.SPEEDFACTOR end
|
|
|
|
for i=#self.particles,1,-1 do
|
|
self.particles[i].draw = true
|
|
self.particles[i].e_vel = self.particles[i].e_vel or dt*self.scale
|
|
self.particles[i].e_prev = self.particles[i].e_curr
|
|
self.particles[i].age = self.particles[i].age + dt
|
|
|
|
self.particles[i].e_curr = math.min(2*math.min((self.particles[i].age/self.lifespan)*self.scale, self.scale*((self.lifespan - self.particles[i].age)/self.lifespan)), self.scale)
|
|
|
|
self.particles[i].e_vel = (self.particles[i].e_curr - self.particles[i].e_prev)*self.scale*dt + (1-self.scale*dt)*self.particles[i].e_vel
|
|
|
|
self.particles[i].scale = self.particles[i].scale + self.particles[i].e_vel
|
|
self.particles[i].scale = math.min(2*math.min((self.particles[i].age/self.lifespan)*self.scale, self.scale*((self.lifespan - self.particles[i].age)/self.lifespan)), self.scale)
|
|
|
|
if self.particles[i].scale < 0 then
|
|
table.remove(self.particles, i)
|
|
else
|
|
self.particles[i].offset.x = self.particles[i].offset.x + self.particles[i].velocity*math.sin(self.particles[i].dir)*dt
|
|
self.particles[i].offset.y = self.particles[i].offset.y + self.particles[i].velocity*math.cos(self.particles[i].dir)*dt
|
|
self.particles[i].facing = self.particles[i].facing + self.particles[i].r_vel*dt
|
|
self.particles[i].velocity = math.max(0, self.particles[i].velocity - self.particles[i].velocity*0.07*dt)
|
|
end
|
|
end
|
|
end
|
|
|
|
function Particles:fade(delay, to)
|
|
G.E_MANAGER:add_event(Event({
|
|
trigger = 'ease',
|
|
timer = self.timer_type,
|
|
blockable = false,
|
|
blocking = false,
|
|
ref_value = 'fade_alpha',
|
|
ref_table = self,
|
|
ease_to = to or 1,
|
|
delay = delay
|
|
}))
|
|
end
|
|
|
|
function Particles:draw(alpha)
|
|
alpha = alpha or 1
|
|
prep_draw(self, 1)
|
|
love.graphics.translate(self.T.w/2, self.T.h/2)
|
|
for k, v in pairs(self.particles) do
|
|
if v.draw then
|
|
love.graphics.push()
|
|
love.graphics.setColor(v.colour[1], v.colour[2], v.colour[3], v.colour[4]*alpha*(1-self.fade_alpha))
|
|
love.graphics.translate(v.offset.x, v.offset.y)
|
|
love.graphics.rotate(v.facing)
|
|
|
|
love.graphics.rectangle('fill', -v.scale/2, -v.scale/2, v.scale, v.scale) -- origin in the middle
|
|
love.graphics.pop()
|
|
end
|
|
end
|
|
love.graphics.pop()
|
|
|
|
add_to_drawhash(self)
|
|
self:draw_boundingrect()
|
|
end
|
|
|
|
function Particles:remove()
|
|
if self.role.major then
|
|
for k, v in pairs(self.role.major.children) do
|
|
if v == self and type(k) == 'number' then
|
|
table.remove(self.role.major.children, k)
|
|
end
|
|
end
|
|
end
|
|
|
|
remove_all(self.children)
|
|
|
|
Moveable.remove(self)
|
|
end
|