aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorne_mene <[email protected]>2026-03-17 22:06:18 +0100
committerne_mene <[email protected]>2026-03-17 22:07:23 +0100
commit518f5e58b14c6659ef1af0665e61b14fd8f00b56 (patch)
tree34b7c07a749b4afea8532560653b6755f4eab0f2
parent27b53e9fdfd3b7f758236657e93e0bc524149603 (diff)
speck bounce and speck reusage
-rw-r--r--src/objs/player.lua7
-rw-r--r--src/objs/specks.lua73
-rw-r--r--src/utils.lua4
3 files changed, 74 insertions, 10 deletions
diff --git a/src/objs/player.lua b/src/objs/player.lua
index 4f05c3b..3f1e2aa 100644
--- a/src/objs/player.lua
+++ b/src/objs/player.lua
@@ -96,6 +96,13 @@ function new_player(x, y)
add_comp(ent, "Player")
add_comp(ent, "Speck_System")
+ ent.speck_sys.interval = 0.05
+
+ ent.speck_sys.lifetime_max = 0.6
+ ent.speck_sys.lifetime_min = 0.3
+
+ ent.speck_sys.forcey = 1000
+ ent.speck_sys.bounce = true
add_comp(ent, "Body", x, y, 8, 14, {
offsetx = -4,
diff --git a/src/objs/specks.lua b/src/objs/specks.lua
index fdfeb26..d9ed5ea 100644
--- a/src/objs/specks.lua
+++ b/src/objs/specks.lua
@@ -9,6 +9,7 @@ function Speck_Sys.new()
pos = {},
vel = {},
+ alive = {},
lifetime = {},
lifetime_max = {},
@@ -16,13 +17,19 @@ function Speck_Sys.new()
scale_end = {}
}
+ self.free_ids = {}
+ self.free_ids_size = 0
+
self.scale_curve = lerp
- self.scale_start_min = 1
- self.scale_start_max = 1
+ self.scale_start_min = 0.8
+ self.scale_start_max = 1.25
self.scale_end_min = 0
self.scale_end_max = 0
+ self.forcex = 0
+ self.forcey = 0
+
self.lifetime_min = 1
self.lifetime_max = 5
@@ -36,34 +43,80 @@ function Speck_Sys.new()
return self
end
+function Speck_Sys:check_bounce(i)
+ if not self.bounce then
+ return false
+ end
+
+ local scn = get_current_scene()
+ assert(scn, "No scene set.")
+
+ return has_tile(
+ scn.tilemap,
+ to_tile_coords(self.data.pos[i].x, self.data.pos[i].y))
+end
+
function Speck_Sys:update(dt)
local data = self.data
+ -- particle spawning
self.spawn_timer = self.spawn_timer - dt
if self.spawn_timer <= 0 then
self.spawn_timer = self.interval
- data.size = data.size + 1
- data.pos[data.size] = { x = self.x, y = self.y }
- data.vel[data.size] = { x = 0, y = 0 }
+ local id
+ if self.free_ids_size > 0 then
+ id = self.free_ids[self.free_ids_size]
+ self.free_ids_size = self.free_ids_size - 1
+ else
+ self.data.size = self.data.size + 1
+ id = self.data.size
+ end
+
+ data.alive[id] = true
+
+ data.pos[id] = { x = self.x, y = self.y }
+ data.vel[id] = { x = 0, y = 0 }
- data.lifetime[data.size] = lmath.random(
+ data.lifetime[id] = randf_range(
self.lifetime_min, self.lifetime_max)
- data.lifetime_max[data.size] = data.lifetime[data.size]
+ data.lifetime_max[id] = data.lifetime[id]
- data.scale_start[data.size] = lmath.random(
+ data.scale_start[id] = randf_range(
self.scale_start_min, self.scale_start_max)
- data.scale_end[data.size] = lmath.random(
+ data.scale_end[id] = randf_range(
self.scale_end_min, self.scale_end_max)
end
+ -- particles processing
for i = 1, data.size do
+ if not data.alive[i] then
+ goto next_speck_update
+ end
+
if data.lifetime[i] <= 0 then
+ data.alive[i] = false
+
+ self.free_ids_size = self.free_ids_size + 1
+ self.free_ids[self.free_ids_size] = i
goto next_speck_update
end
+ data.vel[i].x = data.vel[i].x + self.forcex * dt
+ data.vel[i].y = data.vel[i].y + self.forcey * dt
+
+ -- move and bounce
data.pos[i].x = data.pos[i].x + data.vel[i].x * dt
+ if self:check_bounce(i) then
+ data.vel[i].x = -data.vel[i].x
+ data.pos[i].x = data.pos[i].x + data.vel[i].x * dt
+ end
+
data.pos[i].y = data.pos[i].y + data.vel[i].y * dt
+ if self:check_bounce(i) then
+ data.vel[i].y = -data.vel[i].y
+ data.pos[i].y = data.pos[i].y + data.vel[i].y * dt
+ end
data.lifetime[i] = data.lifetime[i] - dt
@@ -76,7 +129,7 @@ function Speck_Sys:draw()
local data = self.data
for i = 1, data.size do
- if data.lifetime[i] <= 0 then
+ if not data.alive[i] then
goto next_speck_draw
end
diff --git a/src/utils.lua b/src/utils.lua
index 02ca522..56479b8 100644
--- a/src/utils.lua
+++ b/src/utils.lua
@@ -1,4 +1,8 @@
+function randf_range(max, min)
+ return math.random() * (max - min) + min
+end
+
function lerp(a, b, c)
return a + (b - a) * c
end