Advertisement
Guest User

Untitled

a guest
Oct 14th, 2019
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.56 KB | None | 0 0
  1.  
  2. ParticleSystemHandle = class("ParticleSystemHandle")
  3.  
  4. function ParticleSystemHandle:init(psData)
  5.     self.psData = psData
  6.     self.emitters = getParticleSystemEmitters(psData)
  7.     self.claimed = true
  8. end
  9.  
  10. function ParticleSystemHandle:claim()
  11.     if self.claimed then
  12.         error("Claim system twice!")
  13.     else
  14.         self.claimed = true
  15.         self.position = nil
  16.         self:call("reset")
  17.         self:call("start")
  18.     end
  19. end
  20.  
  21. function ParticleSystemHandle:release()
  22.     self.claimed = false
  23.     self:call("stop")
  24. end
  25.  
  26. function ParticleSystemHandle:isClaimed()
  27.     return self.claimed
  28. end
  29.  
  30. function ParticleSystemHandle:call(name, ...)
  31.     for i, emitter in ipairs(self.emitters) do
  32.         emitter.obj[name](emitter.obj, ...)
  33.     end
  34. end
  35.  
  36. function ParticleSystemHandle:emit(x, y, direction)
  37.     if type(x) == "table" then
  38.         self.position = x
  39.         direction = y
  40.         y = nil
  41.     end
  42.  
  43.     for i, emitter in ipairs(self.emitters) do
  44.         if x and y then emitter.obj:setPosition(x, y) end
  45.         if direction then emitter.obj:setDirection(direction) end
  46.         emitter.obj:reset()
  47.         emitter.obj:start()
  48.         emitter.obj:emit(emitter.data.emitAmount)
  49.     end
  50. end
  51.  
  52. function ParticleSystemHandle:isStopped()
  53.     return func_all(self.emitters, function(emitter)
  54.         return emitter.obj:isStopped()
  55.     end)
  56. end
  57.  
  58. function ParticleSystemHandle:isActive()
  59.     return func_any(self.emitters, function(emitter)
  60.         return emitter.obj:isActive()
  61.     end)
  62. end
  63.  
  64. function ParticleSystemHandle:done()
  65.     return func_all(self.emitters, function(emitter)
  66.         if emitter.obj:getEmitterLifetime() >= 0 then
  67.             return not emitter.obj:isActive()
  68.         else
  69.             return emitter.obj:getCount() == 0
  70.         end
  71.     end)
  72. end
  73.  
  74. function ParticleSystemHandle:update(dt)
  75.     for i, emitter in ipairs(self.emitters) do
  76.         emitter.obj:update(dt)
  77.     end
  78. end
  79.  
  80. local blendModes = {"add", "alpha", "subtract", "multiply", "replace", "screen", "lighten", "darken"}
  81. function ParticleSystemHandle:draw()
  82.     local lg = love.graphics
  83.     local oldBlendMode = lg.getBlendMode()
  84.     lg.push()
  85.     if self.position then
  86.         -- this is not setPosition, since that only sets the position where new particles should be spawned
  87.         -- it will not move already spawned particles
  88.         lg.translate(unpack(self.position))
  89.     end
  90.     for i, emitter in ipairs(self.emitters) do
  91.         lg.setColor(255, 255, 255, 255)
  92.         lg.setBlendMode(blendModes[emitter.data.blendMode])
  93.         lg.draw(emitter.obj)
  94.     end
  95.     lg.pop()
  96.     lg.setBlendMode(oldBlendMode)
  97. end
  98.  
  99. ParticleSystemPool = class("ParticleSystemPool")
  100.  
  101. function ParticleSystemPool:init(filename)
  102.     self.psData = loveDoFile("media/particlefx/" .. filename)
  103.     self.systems = {}
  104.     self.scale = {1, 1}
  105. end
  106.  
  107. function ParticleSystemPool:get()
  108.     for i, system in ipairs(self.systems) do
  109.         if system:done() then
  110.             system:release()
  111.         end
  112.  
  113.         if not system:isClaimed() then
  114.             system:claim()
  115.             return system
  116.         end
  117.     end
  118.  
  119.     local system = ParticleSystemHandle(self.psData)
  120.     table.insert(self.systems, system)
  121.     return system
  122. end
  123.  
  124. function ParticleSystemPool:emit(x, y, direction)
  125.     local ps = self:get()
  126.     ps:emit(x, y, direction)
  127. end
  128.  
  129. function ParticleSystemPool:update(dt)
  130.     for _, system in ipairs(self.systems) do
  131.         system:update(dt)
  132.     end
  133. end
  134.  
  135. function ParticleSystemPool:setScale(x, y)
  136.     if y == nil then
  137.         self.scale = {x, x}
  138.     else
  139.         self.scale = {x, y}
  140.     end
  141. end
  142.  
  143. function ParticleSystemPool:draw()
  144.     -- we cannot translate/scale here, because there are already transformations in each emitter
  145.     for _, system in ipairs(self.systems) do
  146.         system:draw()
  147.     end
  148. end
  149.  
  150. function ParticleSystemPool:cleanup()
  151.     self.systems = {}
  152. end
  153.  
  154. fx = {
  155.     airjump = ParticleSystemPool("airjump.lua"),
  156.     dash = ParticleSystemPool("dash.lua"),
  157.     land = ParticleSystemPool("land.lua"),
  158.     hitstun = ParticleSystemPool("hitstun.lua"),
  159.     hit = ParticleSystemPool("hit.lua"),
  160.     fire_stand = ParticleSystemPool("fire_stand.lua"),
  161.     fire_fly = ParticleSystemPool("fire_fly.lua"),
  162.     fireball_explode = ParticleSystemPool("fireball_explode.lua"),
  163.     use_charge = ParticleSystemPool("usecharge.lua"),
  164.     trail = ParticleSystemPool("trail.lua"),
  165.     roots = ParticleSystemPool("roots.lua"),
  166.     magnetize = ParticleSystemPool("magnetize.lua"),
  167.     nessrocket_charge = ParticleSystemPool("nessrocket_charge.lua"),
  168.     nessrocket_shoot = ParticleSystemPool("nessrocket_shoot.lua"),
  169.     saiyajin_charge = ParticleSystemPool("saiyajin_charge.lua"),
  170.     charge_punch = ParticleSystemPool("charge_punch.lua"),
  171.     roots_move = ParticleSystemPool("roots_move.lua"),
  172. }
  173.  
  174. function getParticleSystemEmitters(psData)
  175.     local emitters = {}
  176.  
  177.     for i, emitter in ipairs(psData) do
  178.         local texture = getImage("media/particlefx/" .. emitter.imageName)
  179.         local ps = love.graphics.newParticleSystem(texture, emitter.bufferSize)
  180.  
  181.         local quads = {}
  182.         local w, h = texture:getWidth() / emitter.imagesInStrip, texture:getHeight()
  183.         for i = 1, emitter.imagesInStrip do
  184.             x, y = (i-1)*w, 0
  185.             table.insert(quads, love.graphics.newQuad(x, y, w, h, texture:getWidth(), h))
  186.         end
  187.         ps:setQuads(unpack(quads))
  188.  
  189.         local colors = {}
  190.         local channels = {"r", "g", "b", "a"}
  191.         for i = 1, emitter.colorIndexCount do
  192.             for c = 1, 4 do
  193.                 colors[(i-1)*4 + c] = emitter["color"..i.."_"..channels[c]]
  194.             end
  195.         end
  196.         ps:setColors(unpack(colors))
  197.  
  198.         local sizes = {}
  199.         for i = 1, emitter.sizeIndexCount do
  200.             sizes[i] = emitter["size"..i]
  201.         end
  202.         ps:setSizes(unpack(sizes))
  203.  
  204.         ps:setOffset(emitter.offsetX, emitter.offsetY)
  205.         ps:setEmitterLifetime(emitter.emitterLifetime)
  206.         ps:setEmissionRate(emitter.emissionRate)
  207.         ps:setDirection(emitter.direction * math.pi / 180.0)
  208.         ps:setSpread(emitter.directionSpread * math.pi / 180.0)
  209.         local spreadType = {"uniform", "normal", "none"}
  210.         ps:setAreaSpread(spreadType[emitter.areaSpreadType], emitter.areaSpreadX, emitter.areaSpreadY)
  211.         ps:setParticleLifetime(emitter.particleLifetimeMin, emitter.particleLifetimeMax)
  212.         ps:setRelativeRotation(emitter.relativeRotation > 1)
  213.  
  214.         ps:setSizeVariation(emitter.sizeVariation)
  215.         ps:setRotation(emitter.rotationMin * math.pi / 180.0, emitter.rotationMax * math.pi / 180.0)
  216.         ps:setSpeed(emitter.speedMin, emitter.speedMax)
  217.         ps:setLinearAcceleration(emitter.linAccelXMin, emitter.linAccelYMin, emitter.linAccelXMax, emitter.linAccelYMax)
  218.         ps:setRadialAcceleration(emitter.radAccelMin, emitter.radAccelMax)
  219.         ps:setTangentialAcceleration(emitter.tangAccelMin, emitter.tangAccelMax)
  220.         ps:setLinearDamping(emitter.linDampMin, emitter.linDampMax)
  221.         ps:setSpin(emitter.spinMin, emitter.spinMax)
  222.         ps:setSpinVariation(emitter.spinVariation)
  223.  
  224.         table.insert(emitters, {obj = ps, data = emitter})
  225.     end
  226.  
  227.     return emitters
  228. end
  229.  
  230. function updateFX(dt)
  231.     for name, pool in pairs(fx) do
  232.         pool:update(dt)
  233.     end
  234. end
  235.  
  236. function drawFX()
  237.     if not hideFX then
  238.         for name, pool in pairs(fx) do
  239.             pool:draw()
  240.         end
  241.     end
  242. end
  243.  
  244. function cleanupFX()
  245.     if not hideFX then
  246.         for name, pool in pairs(fx) do
  247.             pool:cleanup()
  248.         end
  249.     end
  250. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement