Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local PARTICLE = {}
- PARTICLE.__index = PARTICLE
- class.GetSet(PARTICLE, "Pos", Vec3(0,0,0))
- class.GetSet(PARTICLE, "Velocity", Vec3(0,0,0))
- class.GetSet(PARTICLE, "Drag", 0.98)
- class.GetSet(PARTICLE, "Size", Vec2(1,1))
- class.GetSet(PARTICLE, "StartSize", 10)
- class.GetSet(PARTICLE, "EndSize", 0)
- class.GetSet(PARTICLE, "StartAlpha", 1)
- class.GetSet(PARTICLE, "EndAlpha", 0)
- class.GetSet(PARTICLE, "LifeTime", 1)
- class.GetSet(PARTICLE, "Texture", NULL)
- class.GetSet(PARTICLE, "Color", Color(1,1,1,1))
- function PARTICLE:SetLifeTime(n)
- self.LifeTime = n
- self.life_end = glfw.GetTime() + n
- end
- local EMITTER = {}
- EMITTER.__index = EMITTER
- class.GetSet(EMITTER, "Rate", 0.1)
- class.GetSet(EMITTER, "EmitCount", 1)
- class.GetSet(EMITTER, "Mode2D", true)
- class.GetSet(EMITTER, "Pos", Vec3(0, 0, 0))
- class.GetSet(EMITTER, "Additive", true)
- function EMITTER:IsValid()
- return true
- end
- local emitters = {}
- function Emitter()
- local self = setmetatable({}, EMITTER)
- self.particles = {}
- self.last_emit = 0
- table.insert(emitters, self)
- return self
- end
- function EMITTER:Remove()
- for k,v in pairs(emitters) do
- if v == self then
- table.remove(emitters, k)
- break
- end
- end
- utilities.MakeNULL(self)
- end
- function EMITTER:Think(dt)
- local time = glfw.GetTime()
- if self.Rate == 0 then
- self:Emit()
- else
- if self.last_emit < time then
- self:Emit()
- self.last_emit = time + self.Rate
- end
- end
- for key, p in pairs(self.particles) do
- if p.life_end < time then
- self.particles[key] = nil
- else
- -- velocity
- p.Pos.x = p.Pos.x + (p.Velocity.x * dt)
- p.Pos.y = p.Pos.y + (p.Velocity.y * dt)
- -- friction
- p.Velocity.x = p.Velocity.x * p.Drag
- p.Velocity.y = p.Velocity.y * p.Drag
- p.life_mult = math.clamp(p.life_end - time, 0, 1)
- end
- end
- end
- function EMITTER:Draw()
- local old = render.GetAdditive()
- render.SetAdditive(self.Additive)
- if self.Mode2D then
- for _, p in pairs(self.particles) do
- if p.Texture:IsValid() then
- surface.SetTexture(p.Texture)
- else
- surface.SetWhiteTexture()
- end
- local size = math.lerp(p.life_mult, p.EndSize, p.StartSize)
- local alpha = math.lerp(p.life_mult, p.EndAlpha, p.StartAlpha)
- local w = size * p.Size.x
- local h = size * p.Size.y
- surface.Color(p.Color.r, p.Color.g, p.Color.b, p.Color.a * alpha)
- surface.DrawRect(
- p.Pos.x - w*0.5,
- p.Pos.y - h*0.5,
- w,
- h
- )
- end
- else
- -- 3d here
- end
- render.SetAdditive(old)
- end
- function EMITTER:GetParticles()
- return self.particles
- end
- function EMITTER:Emit()
- for i = 1, self.EmitCount do
- local p = setmetatable({}, PARTICLE)
- p:SetPos(self:GetPos():Copy())
- p.life_mult = 1
- p:SetLifeTime(1)
- self:OnEmit(p)
- table.insert(self.particles, p)
- end
- end
- event.AddListener("OnDraw2D", "particles", function(dt)
- surface.SetWhiteTexture()
- surface.Color(0,0,0,1)
- surface.DrawRect(0,0,surface.GetScreenSize())
- for _, emitter in pairs(emitters) do
- emitter:Draw()
- end
- end)
- event.AddListener("OnUpdate", "particles", function(dt)
- surface.SetWhiteTexture()
- surface.Color(0,0,0,1)
- surface.DrawRect(0,0,surface.GetScreenSize())
- for _, emitter in pairs(emitters) do
- emitter:Think(dt)
- if wait(1) then
- print(table.count(emitter:GetParticles()))
- end
- end
- end)
- window.Open(1024, 1024)
- -- test
- local emitter = Emitter()
- emitter:SetPos(Vec3(50,50))
- emitter:SetRate(0)
- emitter:SetEmitCount(100)
- local sphere = Texture(64, 64):Fill(function(x, y)
- x = x / 64
- y = y / 64
- x = x - 1
- y = y - 1.5
- x = x * math.pi
- y = y * math.pi
- local a = math.sin(x) * math.cos(y)
- a = a ^ 32
- return 255, 255, 255, a * 128
- end)
- function emitter:OnEmit(p)
- p:SetTexture(sphere)
- p:SetPos(Vec3((window.GetSize()/2):Unpack()) + Vec3() + Vec3():GetRandom(-10,10))
- p:SetVelocity(Vec3():GetRandom():GetAng3():GetForward() * 200)
- p:SetLifeTime(math.randomf(1,5))
- p:SetStartSize(math.randomf(10,20)*2)
- p:SetStartAlpha(0)
- p:SetEndAlpha(1)
- p:SetColor(HSVToColor(glfw.GetTime()/5, 0.5))
- end
Advertisement
Add Comment
Please, Sign In to add comment