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
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
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 (collides(box, hurtbox(candidate))) add(found, candidate)
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
return found
end -- end of closure def
end
-->8