summaryrefslogtreecommitdiff
path: root/dustParticle.lua
diff options
context:
space:
mode:
Diffstat (limited to 'dustParticle.lua')
-rw-r--r--dustParticle.lua135
1 files changed, 135 insertions, 0 deletions
diff --git a/dustParticle.lua b/dustParticle.lua
new file mode 100644
index 0000000..8e7edd4
--- /dev/null
+++ b/dustParticle.lua
@@ -0,0 +1,135 @@
+local DustParticle = {}
+DustParticle.__index = DustParticle
+
+local MAX_DUST = 30
+local DRIFT_SPEED_MIN = 4
+local DRIFT_SPEED_MAX = 12
+local WOBBLE_AMP_MIN = 3
+local WOBBLE_AMP_MAX = 8
+local WOBBLE_FREQ_MIN = 0.8
+local WOBBLE_FREQ_MAX = 2.5
+local GLOW_FREQ_MIN = 1.5
+local GLOW_FREQ_MAX = 4.0
+local GLOW_RADIUS_MIN = 2
+local GLOW_RADIUS_MAX = 5
+local MARGIN = 16
+
+local DUST_COLORS = {
+ {1.0, 0.95, 0.75},
+ {0.85, 0.9, 1.0},
+ {1.0, 0.85, 0.6},
+ {0.75, 0.85, 1.0},
+}
+
+function DustParticle.new(x, y)
+ local self = setmetatable({}, DustParticle)
+ self.x = x
+ self.y = y
+
+ local angle = math.random() * math.pi * 2
+ local speed = DRIFT_SPEED_MIN + math.random() * (DRIFT_SPEED_MAX - DRIFT_SPEED_MIN)
+ self.dx = math.cos(angle) * speed
+ self.dy = math.sin(angle) * speed
+
+ self.perpX = -math.sin(angle)
+ self.perpY = math.cos(angle)
+
+ self.wobbleAmp = WOBBLE_AMP_MIN + math.random() * (WOBBLE_AMP_MAX - WOBBLE_AMP_MIN)
+ self.wobbleFreq = WOBBLE_FREQ_MIN + math.random() * (WOBBLE_FREQ_MAX - WOBBLE_FREQ_MIN)
+ self.wobblePhase = math.random() * math.pi * 2
+
+ self.glowFreq = GLOW_FREQ_MIN + math.random() * (GLOW_FREQ_MAX - GLOW_FREQ_MIN)
+ self.glowPhase = math.random() * math.pi * 2
+
+ self.baseAlpha = 0.15 + math.random() * 0.25
+ self.color = DUST_COLORS[math.random(#DUST_COLORS)]
+ self.time = 0
+ return self
+end
+
+function DustParticle:update(dt)
+ self.time = self.time + dt
+ local wobble = math.sin(self.time * self.wobbleFreq + self.wobblePhase) * self.wobbleAmp
+ self.x = self.x + (self.dx + self.perpX * wobble * 0.3) * dt
+ self.y = self.y + (self.dy + self.perpY * wobble * 0.3) * dt
+end
+
+function DustParticle:draw()
+ local glowT = math.sin(self.time * self.glowFreq + self.glowPhase)
+ local glowRadius = GLOW_RADIUS_MIN + (GLOW_RADIUS_MAX - GLOW_RADIUS_MIN) * (glowT * 0.5 + 0.5)
+ local alpha = self.baseAlpha * (0.6 + 0.4 * (glowT * 0.5 + 0.5))
+
+ love.graphics.setBlendMode("add")
+ love.graphics.setColor(self.color[1], self.color[2], self.color[3], alpha * 0.4)
+ love.graphics.circle("fill", self.x, self.y, glowRadius)
+ love.graphics.setColor(self.color[1], self.color[2], self.color[3], alpha)
+ love.graphics.circle("fill", self.x, self.y, 1)
+ love.graphics.setBlendMode("alpha")
+ love.graphics.setColor(1, 1, 1, 1)
+end
+
+function DustParticle:isOutOfBounds(viewX, viewY, viewW, viewH)
+ return self.x < viewX - MARGIN or self.x > viewX + viewW + MARGIN
+ or self.y < viewY - MARGIN or self.y > viewY + viewH + MARGIN
+end
+
+local DustSystem = {}
+DustSystem.__index = DustSystem
+
+function DustSystem.new()
+ local self = setmetatable({}, DustSystem)
+ self.particles = {}
+ self.spawned = false
+ return self
+end
+
+function DustSystem:update(dt, camX, camY, camW, camH)
+ if not self.spawned then
+ for _ = 1, MAX_DUST do
+ local x = camX + math.random() * camW
+ local y = camY + math.random() * camH
+ table.insert(self.particles, DustParticle.new(x, y))
+ end
+ self.spawned = true
+ end
+
+ for _, p in ipairs(self.particles) do
+ p:update(dt)
+ end
+
+ for i = #self.particles, 1, -1 do
+ local p = self.particles[i]
+ if p:isOutOfBounds(camX, camY, camW, camH) then
+ local edge = math.random(4)
+ local x, y
+ if edge == 1 then
+ x = camX - MARGIN * 0.5
+ y = camY + math.random() * camH
+ elseif edge == 2 then
+ x = camX + camW + MARGIN * 0.5
+ y = camY + math.random() * camH
+ elseif edge == 3 then
+ x = camX + math.random() * camW
+ y = camY - MARGIN * 0.5
+ else
+ x = camX + math.random() * camW
+ y = camY + camH + MARGIN * 0.5
+ end
+ self.particles[i] = DustParticle.new(x, y)
+ end
+ end
+
+ while #self.particles < MAX_DUST do
+ local x = camX + math.random() * camW
+ local y = camY + math.random() * camH
+ table.insert(self.particles, DustParticle.new(x, y))
+ end
+end
+
+function DustSystem:draw()
+ for _, p in ipairs(self.particles) do
+ p:draw()
+ end
+end
+
+return DustSystem