From 0f791b193cf0d34f2a1bfb9c2c2e00307b31a37a Mon Sep 17 00:00:00 2001 From: Kistaro Windrider Date: Fri, 20 Jun 2025 18:50:04 -0700 Subject: [PATCH] more efficient collision iteration, fix eternal shots --- vacuum_gambit.p8 | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/vacuum_gambit.p8 b/vacuum_gambit.p8 index 19f37e8..e25bc69 100644 --- a/vacuum_gambit.p8 +++ b/vacuum_gambit.p8 @@ -245,13 +245,13 @@ function updategame() if not ps.dead then ps:move() local pbox = hurtbox(ps) - for es in all(eship_collider:get_collisions(pbox)) do + for es in eship_collider:iterate_collisions(pbox) do ps:hitship(es) if(es:hitship(ps)) eship_collider:yoink(es) end ebullets:strip(function(eb) -- loopify this when split moves implemented - eb:move() + if (eb:move()) return true if (not collides(pbox, hurtbox(eb))) return ps:hitbullet(eb) return eb:hitship(ps) @@ -261,7 +261,7 @@ function updategame() end pbullets:strip(function(pb) - for es in all(eship_collider:get_collisions(hurtbox(pb))) do + for es in eship_collider:iterate_collisions(hurtbox(pb)) do if (es:hitbullet(pb)) eship_collider:yoink(es) if (pb:hitship(es)) return true end @@ -1468,22 +1468,28 @@ function collider:yoink(item) end end -function collider:get_collisions(box) - local found = { } +function collider:iterate_collisions(box) local seen = { } local bucket_ids = collider_indexes(box) - for b_idx in all(bucket_ids) do - local bucket = self[b_idx] - if bucket then - for candidate in all(bucket) do - if not (seen[candidate] or self.suppress[candidate]) then - seen[candidate] = true - if (collides(box, hurtbox(candidate))) add(found, candidate) - end + local bii, bidl, bucket, bi, blen = 1, #bucket_ids, false, 1, 0 + return function() + while bii <= bidl do + if not bucket then + bucket,blen = self[bucket_ids[bii]],0 + if (bucket) blen=#bucket end + while bi <= blen do + local candidate = bucket[bi] + bi += 1 + if not seen[candidate] then + seen[candidate] = true + if (not self.suppress[candidate] and collides(box, hurtbox(candidate))) return candidate + end + end -- done with this bucket + bi=1 + bii += 1 end - end - return found + end -- end of closure def end -->8