more efficient collision iteration, fix eternal shots

This commit is contained in:
2025-06-20 18:50:04 -07:00
parent d3351d9a05
commit 0f791b193c

View File

@ -245,13 +245,13 @@ function updategame()
if not ps.dead then if not ps.dead then
ps:move() ps:move()
local pbox = hurtbox(ps) 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) ps:hitship(es)
if(es:hitship(ps)) eship_collider:yoink(es) if(es:hitship(ps)) eship_collider:yoink(es)
end end
ebullets:strip(function(eb) ebullets:strip(function(eb)
-- loopify this when split moves implemented -- loopify this when split moves implemented
eb:move() if (eb:move()) return true
if (not collides(pbox, hurtbox(eb))) return if (not collides(pbox, hurtbox(eb))) return
ps:hitbullet(eb) ps:hitbullet(eb)
return eb:hitship(ps) return eb:hitship(ps)
@ -261,7 +261,7 @@ function updategame()
end end
pbullets:strip(function(pb) 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 (es:hitbullet(pb)) eship_collider:yoink(es)
if (pb:hitship(es)) return true if (pb:hitship(es)) return true
end end
@ -1468,22 +1468,28 @@ function collider:yoink(item)
end end
end end
function collider:get_collisions(box) function collider:iterate_collisions(box)
local found = { }
local seen = { } local seen = { }
local bucket_ids = collider_indexes(box) local bucket_ids = collider_indexes(box)
for b_idx in all(bucket_ids) do local bii, bidl, bucket, bi, blen = 1, #bucket_ids, false, 1, 0
local bucket = self[b_idx] return function()
if bucket then while bii <= bidl do
for candidate in all(bucket) do if not bucket then
if not (seen[candidate] or self.suppress[candidate]) then bucket,blen = self[bucket_ids[bii]],0
seen[candidate] = true if (bucket) blen=#bucket
if (collides(box, hurtbox(candidate))) add(found, candidate)
end
end 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
end end -- end of closure def
return found
end end
-->8 -->8