## Collision detection between bullets [SOLVED]

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
test
Prole
Posts: 28
Joined: Sun Apr 14, 2019 2:36 pm

### Collision detection between bullets [SOLVED]

I have this code

Code: Select all

for i, v in ipairs(listOfBullets) do v:update(dt) end
how can I check collision between two v's.
Last edited by test on Tue May 07, 2019 7:15 pm, edited 1 time in total.

raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

### Re: Collision detection between bullets

Code: Select all

for i, v in ipairs(listOfBullets) do
v:update(dt)
for ii, vv in ipairs(listOfBullets) do
if vv ~= v and checkCollison(v,vv) then
resolveCollision(v,vv)
end
end
end

test
Prole
Posts: 28
Joined: Sun Apr 14, 2019 2:36 pm

### Re: Collision detection between bullets

Thanks raidho36. It works now but SOMETIMES one bullet is not be destroyed after collision of two bullets. I want both to be destroyed.

Code: Select all

for i, v in ipairs(projectiles) do
v.x = v.x + v.speed * dt

for ii = 1, 2 do
if CheckCollision(v.x, v.y, v.w, v.h, p[ii].x, p[ii].y, p[ii].w, p[ii].h) then
if ii == v.id then
else
table.remove(projectiles, i)
end
end
end

for ii, vv in ipairs(projectiles) do
if vv ~= v and CheckCollision(v.x, v.y, v.w, v.h, vv.x, vv.y, vv.w,vv.h) then
table.remove(projectiles, i)
table.remove(projectiles, ii)
end
end
end

pgimeno
Party member
Posts: 2123
Joined: Sun Oct 18, 2015 2:58 pm

### Re: Collision detection between bullets

Removal of two projectiles while looping is a bit more complicated. Best is to defer deletion, so you don't skip any checks. Logically, everything happens after the update; otherwise you might detect a collision between a projectile that is not yet updated and one that is, and that collision would be bogus.

Also, you don't need to loop over the players just to check if the bullet hits the right player. If your player IDs are 1 and 2, then the formula (3 - player_id) will give you the other player.

Code: Select all

-- Update all projectiles at once
for i = 1, #projectiles do
local v = projectiles[i]
v.x = v.x + v.speed * dt
end

local deleted = {}
local player_collision = false

-- Check collisions
for i = 1, #projectiles do
local v = projectiles[i]
local other_player_id = 3 - v.id
if CheckCollision(v, p[other_player_id]) then
deleted[i] = true
-- insert here the action to inflict damage to the player
end

for j = i + 1, #projectiles do
local vv = projectiles[j]
if CheckCollision(v, vv) then
deleted[i] = true
deleted[j] = true
end
end
end

-- Remove obsolete bullets
for i = #projectiles, 1, -1 do
if deleted[i] then
table.remove(projectiles, i)
end
end


ivan
Party member
Posts: 1554
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

### Re: Collision detection between bullets

pgimeno is right, you could remove the elements during iteration, as long as you iterate in reverse:

Code: Select all

for i = #list, 1, -1 do
for j = i - 1, 1, -1 do
if checkCollisions(list[i], list[j]) then
table.remove(list, i)
table.remove(list, j)
break
end
end
end

pgimeno
Party member
Posts: 2123
Joined: Sun Oct 18, 2015 2:58 pm

### Re: Collision detection between bullets

My concern with not deferring removal is this:

Imagine you have three bullets colliding. To me, logically all three should be removed. But if they are removed in pairs, one of them could survive.

Example in ASCII art:

Code: Select all

    +--------+
|   3    |
|        |
+---+---+  +-+-----+
|   |   |  | |     |
|   +---+--+-+     |
| 1     |  |    2  |
|       |  |       |
+-------+  +-------+

In that situation, if you loop backwards and find that 2 and 3 are colliding, and you remove them, you won't find the collision between 1 and 3, therefore 1 will not be removed. Also, the one that won't be removed will depend on the insertion order of bullets, which feels wrong to me.

The only solution I can imagine for that problem, as I said, is deferring the deletion until all checks are finished.

### Who is online

Users browsing this forum: No registered users and 15 guests