I’m trying to create a relatively simple particle system for a firework display, based on an object-oriented paradigm. The issue I’m having is trying to properly dispose of an object when it’s no longer needed.
I have three scripts:
- Everything begins with a local script. Using Heartbeat, there’s a 10% chance I try to loosely create a firework display. This utilises the Firework module I have, which then in turn uses the Particle module.
local Firework = require(script.Firework)
local fireworks = {}
game:GetService("RunService").Heartbeat:Connect(function()
if math.random() < 0.1 then
table.insert(fireworks, Firework.new())
end
for i = 1, #fireworks do
if fireworks[i] then
fireworks[i].update()
fireworks[i].show()
else
table.remove(fireworks, i)
end
end
end)
- Here’s the Particle module, which Firework inherits (there’s no actual inheritance though, at least as far as I’m aware, I’m still coming to grabs with OOP). In brevity, it handles the creation, rendering and deletion of the actual particle instances. I’ve tried deleting the actual particle, looping through itself and setting values to nil, and then setting the entire class to nil after.
local Particle = {}
Particle.__index = Particle
function Particle.new(x, y)
local self = {}
self.pos = Vector2.new(x, y)
self.vel = Vector2.new(0, math.random(-12, -8))
self.acc = Vector2.new(0, 0)
self.point = nil
self.applyForce = function(force)
self.acc = self.acc + force
end
self.update = function()
self.vel = self.vel + self.acc
self.pos = self.pos + self.vel
self.acc = self.acc * 0
end
self.show = function()
if not self.point then
local p = Instance.new("Frame")
p.Parent = script.Parent.Parent
p.Size = UDim2.new(0, 5, 0, 5)
p.BorderSizePixel = 0
p.Position = UDim2.new(0, self.pos.x, 0, self.pos.y)
self.point = p
else
self.point.Position = UDim2.new(0, self.pos.x, 0, self.pos.y)
end
end
self.destroy = function()
self.point:Destroy()
for i, v in next, self do
v = nil
end
self = nil
end
setmetatable(self, {__index = Particle})
return self
end
return Particle
- This is the Firework module, nothing spectacular, it just creates the particle.
local Firework = {}
Firework.__index = Firework
local Particle = require(script.Parent.Particle)
function Firework.new()
local self = {}
self.gravity = Vector2.new(0, 0.2)
self.firework = Particle.new(math.random(script.Parent.Parent.AbsoluteSize.X), script.Parent.Parent.AbsoluteSize.Y)
self.update = function()
if self.firework then
self.firework.applyForce(self.gravity)
self.firework.update()
if self.firework.vel.y >= 0 then
self.firework.destroy()
end
else
return
end
end
self.show = function()
self.firework.show()
end
setmetatable(self, {__index = Firework})
return self
end
return Firework
I suspect that it might have something to do with the Firework object in the local script still being referenced, even when it doesn’t exist? I’ve looked a little at weak tables, and I’m not sure how to implement them or if it’ll even solve the issue.
You can see the particles accelerate upwards and then when it should (and it does, if it wasn’t for the error) fall back down with gravity, that’s when I delete it and get the issue.
I apologise in advance if I’m not doing this whole topic thing right, this is my first time.