I've been playing around with the idea of creating a particle system in pure Lua that can run on the Solarus engine. Unfortunately, I'm pretty new to Lua and the draft that I'm working on now doesn't appear to be working. I think the idea behind it is sound, but I can't get it to display correctly so I can test it!
particles.lua (based off of a Love engine particle system, found at https://github.com/SimonLarsen/sienna/blob/master/particles.lua)
An example map script:
Any thoughts? Is this a lost cause or am I just way off base?
particles.lua (based off of a Love engine particle system, found at https://github.com/SimonLarsen/sienna/blob/master/particles.lua)
Code Select
local particle_system = {}
function particle_system:new(game)
local object = {}
setmetatable(object, self)
self.__index = self
object:initialize(game)
return object
end
function particle_system:initialize(game)
self.game = game
if not self.time then self.time = 1 end
if not self.count then self.count = 5 end
if not self.color then self.color = {255, 255, 255} end
if self.type == "sparkle" then
self.alive = true
self.particles = {}
for i=1, self.count do
self.particles[i] = {}
self.particles[i].x = x
self.particles[i].xspeed = math.random(-100,100)
self.particles[i].y = y
self.particles[i].yspeed = math.random(-200,50) + (self.ysp or 0)
end
return self
elseif self.type == "dust" then
self.alive = true
self.time = 0
self.x = x
self.y = y
return self
end
end
function particle_system:on_update()
self.time = self.time - 1
if self.type == "sparkle" then
if self.time < 0 then
self.alive = false
return
end
for i,v in ipairs(self.particles) do
v.x = v.x + v.xspeed*dt
v.yspeed = v.yspeed + 500*dt
v.y = v.y + v.yspeed*dt
end
elseif self.type == "dust" then
if self.time > 0.25 then
self.alive = false
return
end
end
end
function particle_system:on_draw(dst_surface)
if self.type == "sparkle" then
for i,v in ipairs(self.particles) do
dst_surface:fill_color(self.color, 0.5+v.x, 0.5+v.y, 1, 1)
end
elseif self.type == "dust" then
dst_surface:fill_color(self.color, self.x-self.time*16, self.y-self.time*16, 1, 1)
dst_surface:fill_color(self.color, self.x+self.time*16, self.y-self.time*16, 1, 1)
dst_surface:fill_color(self.color, self.x-self.time*16, self.y+self.time*16, 1, 1)
dst_surface:fill_color(self.color, self.x+self.time*16, self.y+self.time*16, 1, 1)
else
dst_surface:clear()
end
end
function particle_system:set_type(type)
self.type = type
end
function particle_system:set_position(x, y, layer)
self.x = x
self.y = y
self.layer = layer or 1
end
function particle_system:set_particle_count(count)
self.count = count
end
function particle_system:set_particle_color(color)
self.color = color
end
function particle_system:set_decay_time(time)
self.time = time
end
function particle_system:set_y_speed(ysp)
self.ysp = ysp
end
return particle_system
An example map script:
Code Select
local map = ...
local game = map:get_game()
local particle_system = require("particles")
function sensor:on_activated()
local emitter = particle_system:new(game)
emitter:set_type("sparkle")
emitter:set_position(100, 100)
end
function map:on_update()
if emitter ~= nil then emitter:on_update() end
end
function map:on_draw(dst_surface)
if emitter ~= nil then emitter:on_draw(dst_surface) end
end
Any thoughts? Is this a lost cause or am I just way off base?