Initial Commit - 1.0.0k
This commit is contained in:
177
engine/particles.lua
Normal file
177
engine/particles.lua
Normal file
@@ -0,0 +1,177 @@
|
||||
---@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
|
||||
Reference in New Issue
Block a user