Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ParticleSystemHandle = class("ParticleSystemHandle")
- function ParticleSystemHandle:init(psData)
- self.psData = psData
- self.emitters = getParticleSystemEmitters(psData)
- self.claimed = true
- end
- function ParticleSystemHandle:claim()
- if self.claimed then
- error("Claim system twice!")
- else
- self.claimed = true
- self.position = nil
- self:call("reset")
- self:call("start")
- end
- end
- function ParticleSystemHandle:release()
- self.claimed = false
- self:call("stop")
- end
- function ParticleSystemHandle:isClaimed()
- return self.claimed
- end
- function ParticleSystemHandle:call(name, ...)
- for i, emitter in ipairs(self.emitters) do
- emitter.obj[name](emitter.obj, ...)
- end
- end
- function ParticleSystemHandle:emit(x, y, direction)
- if type(x) == "table" then
- self.position = x
- direction = y
- y = nil
- end
- for i, emitter in ipairs(self.emitters) do
- if x and y then emitter.obj:setPosition(x, y) end
- if direction then emitter.obj:setDirection(direction) end
- emitter.obj:reset()
- emitter.obj:start()
- emitter.obj:emit(emitter.data.emitAmount)
- end
- end
- function ParticleSystemHandle:isStopped()
- return func_all(self.emitters, function(emitter)
- return emitter.obj:isStopped()
- end)
- end
- function ParticleSystemHandle:isActive()
- return func_any(self.emitters, function(emitter)
- return emitter.obj:isActive()
- end)
- end
- function ParticleSystemHandle:done()
- return func_all(self.emitters, function(emitter)
- if emitter.obj:getEmitterLifetime() >= 0 then
- return not emitter.obj:isActive()
- else
- return emitter.obj:getCount() == 0
- end
- end)
- end
- function ParticleSystemHandle:update(dt)
- for i, emitter in ipairs(self.emitters) do
- emitter.obj:update(dt)
- end
- end
- local blendModes = {"add", "alpha", "subtract", "multiply", "replace", "screen", "lighten", "darken"}
- function ParticleSystemHandle:draw()
- local lg = love.graphics
- local oldBlendMode = lg.getBlendMode()
- lg.push()
- if self.position then
- -- this is not setPosition, since that only sets the position where new particles should be spawned
- -- it will not move already spawned particles
- lg.translate(unpack(self.position))
- end
- for i, emitter in ipairs(self.emitters) do
- lg.setColor(255, 255, 255, 255)
- lg.setBlendMode(blendModes[emitter.data.blendMode])
- lg.draw(emitter.obj)
- end
- lg.pop()
- lg.setBlendMode(oldBlendMode)
- end
- ParticleSystemPool = class("ParticleSystemPool")
- function ParticleSystemPool:init(filename)
- self.psData = loveDoFile("media/particlefx/" .. filename)
- self.systems = {}
- self.scale = {1, 1}
- end
- function ParticleSystemPool:get()
- for i, system in ipairs(self.systems) do
- if system:done() then
- system:release()
- end
- if not system:isClaimed() then
- system:claim()
- return system
- end
- end
- local system = ParticleSystemHandle(self.psData)
- table.insert(self.systems, system)
- return system
- end
- function ParticleSystemPool:emit(x, y, direction)
- local ps = self:get()
- ps:emit(x, y, direction)
- end
- function ParticleSystemPool:update(dt)
- for _, system in ipairs(self.systems) do
- system:update(dt)
- end
- end
- function ParticleSystemPool:setScale(x, y)
- if y == nil then
- self.scale = {x, x}
- else
- self.scale = {x, y}
- end
- end
- function ParticleSystemPool:draw()
- -- we cannot translate/scale here, because there are already transformations in each emitter
- for _, system in ipairs(self.systems) do
- system:draw()
- end
- end
- function ParticleSystemPool:cleanup()
- self.systems = {}
- end
- fx = {
- airjump = ParticleSystemPool("airjump.lua"),
- dash = ParticleSystemPool("dash.lua"),
- land = ParticleSystemPool("land.lua"),
- hitstun = ParticleSystemPool("hitstun.lua"),
- hit = ParticleSystemPool("hit.lua"),
- fire_stand = ParticleSystemPool("fire_stand.lua"),
- fire_fly = ParticleSystemPool("fire_fly.lua"),
- fireball_explode = ParticleSystemPool("fireball_explode.lua"),
- use_charge = ParticleSystemPool("usecharge.lua"),
- trail = ParticleSystemPool("trail.lua"),
- roots = ParticleSystemPool("roots.lua"),
- magnetize = ParticleSystemPool("magnetize.lua"),
- nessrocket_charge = ParticleSystemPool("nessrocket_charge.lua"),
- nessrocket_shoot = ParticleSystemPool("nessrocket_shoot.lua"),
- saiyajin_charge = ParticleSystemPool("saiyajin_charge.lua"),
- charge_punch = ParticleSystemPool("charge_punch.lua"),
- roots_move = ParticleSystemPool("roots_move.lua"),
- }
- function getParticleSystemEmitters(psData)
- local emitters = {}
- for i, emitter in ipairs(psData) do
- local texture = getImage("media/particlefx/" .. emitter.imageName)
- local ps = love.graphics.newParticleSystem(texture, emitter.bufferSize)
- local quads = {}
- local w, h = texture:getWidth() / emitter.imagesInStrip, texture:getHeight()
- for i = 1, emitter.imagesInStrip do
- x, y = (i-1)*w, 0
- table.insert(quads, love.graphics.newQuad(x, y, w, h, texture:getWidth(), h))
- end
- ps:setQuads(unpack(quads))
- local colors = {}
- local channels = {"r", "g", "b", "a"}
- for i = 1, emitter.colorIndexCount do
- for c = 1, 4 do
- colors[(i-1)*4 + c] = emitter["color"..i.."_"..channels[c]]
- end
- end
- ps:setColors(unpack(colors))
- local sizes = {}
- for i = 1, emitter.sizeIndexCount do
- sizes[i] = emitter["size"..i]
- end
- ps:setSizes(unpack(sizes))
- ps:setOffset(emitter.offsetX, emitter.offsetY)
- ps:setEmitterLifetime(emitter.emitterLifetime)
- ps:setEmissionRate(emitter.emissionRate)
- ps:setDirection(emitter.direction * math.pi / 180.0)
- ps:setSpread(emitter.directionSpread * math.pi / 180.0)
- local spreadType = {"uniform", "normal", "none"}
- ps:setAreaSpread(spreadType[emitter.areaSpreadType], emitter.areaSpreadX, emitter.areaSpreadY)
- ps:setParticleLifetime(emitter.particleLifetimeMin, emitter.particleLifetimeMax)
- ps:setRelativeRotation(emitter.relativeRotation > 1)
- ps:setSizeVariation(emitter.sizeVariation)
- ps:setRotation(emitter.rotationMin * math.pi / 180.0, emitter.rotationMax * math.pi / 180.0)
- ps:setSpeed(emitter.speedMin, emitter.speedMax)
- ps:setLinearAcceleration(emitter.linAccelXMin, emitter.linAccelYMin, emitter.linAccelXMax, emitter.linAccelYMax)
- ps:setRadialAcceleration(emitter.radAccelMin, emitter.radAccelMax)
- ps:setTangentialAcceleration(emitter.tangAccelMin, emitter.tangAccelMax)
- ps:setLinearDamping(emitter.linDampMin, emitter.linDampMax)
- ps:setSpin(emitter.spinMin, emitter.spinMax)
- ps:setSpinVariation(emitter.spinVariation)
- table.insert(emitters, {obj = ps, data = emitter})
- end
- return emitters
- end
- function updateFX(dt)
- for name, pool in pairs(fx) do
- pool:update(dt)
- end
- end
- function drawFX()
- if not hideFX then
- for name, pool in pairs(fx) do
- pool:draw()
- end
- end
- end
- function cleanupFX()
- if not hideFX then
- for name, pool in pairs(fx) do
- pool:cleanup()
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement