## Collision detection problem

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
chingydongy
Prole
Posts: 5
Joined: Sat Jan 20, 2018 4:56 pm

### Collision detection problem

Hello everyone, I have been on this code for the past few months, since I never have the time to work on it, I mostly left it as it is, with only small improvements anytime I can get my hands on it. My question here is, why in all hell isn't the collision detection working with the player/enemy as it is with bullet/enemy? Does it have to do with the fact that both the enemies and bullets are inserted into a table, and the player isn't?
Anyway, here's the code, everything else works fine, but it's just the collcheck(dt) parts that are making me bash my head on a wall.

Code: Select all

require("player")
enemy = {}
enemySpeed = 80
math.randomseed(os.time())
score = 0
enemyNumber = 5
killTimeStart = 10 -- time limit/ level
killTime = killTimeStart
maxw, maxh = love.window.getDesktopDimensions(display)
timer = 0
spawnTime = 5 -- delay of spawn in seconds
round = 4 -- this is the amount of time that is multiplied by delta time (1s) to add to time allowed for the next round
function enemySpawn(x,y,w,h)
for i = 1, enemyNumber do
enemy[#enemy + 1] = {x = math.random(0 and player.x - 320, player.x + 300 and maxw - 64), y = math.random(0 and player.y - 320, player.y + 300 and maxh - 64), w = 64, h = 64}
end
if #enemy <= enemyNumber then
enemyNumber = enemyNumber + math.random(1,3)
end
angery = love.graphics.newImage("enemy.png")
end
function collcheck(dt)
for i,v in ipairs(enemy) do      --collision check for bullet vs enemy and player vs enemy
for a,b in ipairs(bullet) do
if b.x < v.x+64 and b.y < v.y+64 and b.x > v.x-8 and b.y > v.y-8 then
table.remove(enemy, i)
table.remove(bullet, a)
doink:play()
score = score + 1
end
end
end
for i,v in ipairs(player) do      --collision check for bullet vs enemy and player vs enemy
for a,b in ipairs(enemy) do
if v.x < b.x+64 and v.y < b.y+64 and v.x > b.x-20 and v.y > b.y-20 then
table.remove(enemy,i)
love.event.quit()
end
end
end
end
function enemy:update(dt)
killTime = killTime - dt
if killTime < 0 and #enemy > 0 then
killTime = killTimeStart
end
if killTime >=0 and #enemy == 0 then -- if there's remaining kill time and there are no enemies on the screen, increase the round time by Xs
killTime = killTime + round*dt -- done
end
if #enemy == 0 then -- if all enemies are dead, start the timer for the next round (5s)
timer = timer + dt
if timer > spawnTime then
enemySpawn()
timer = 0
end
end
collcheck()
end
function enemy:draw()
for i,v in ipairs(enemy) do
love.graphics.draw(angery, v.x, v.y)
end
end
function enemymove(dt)
for i,v in ipairs(enemy) do
enemyDirectionX = player.x - v.x
enemyDirectionY = player.y - v.y
distance = math.sqrt(enemyDirectionX * enemyDirectionX + enemyDirectionY * enemyDirectionY)
end

if distance ~= 0 then
for i,v in ipairs(enemy) do
v.x = v.x + enemyDirectionX / distance * enemySpeed * dt
v.y = v.y + enemyDirectionY / distance * enemySpeed * dt
end
end
end


The important part is:

Code: Select all

function collcheck(dt)
for i,v in ipairs(enemy) do      --collision check for bullet vs enemy and player vs enemy
for a,b in ipairs(bullet) do
if b.x < v.x+64 and b.y < v.y+64 and b.x > v.x-8 and b.y > v.y-8 then
table.remove(enemy, i)
table.remove(bullet, a)
doink:play()
score = score + 1
end
end
end
for i,v in ipairs(player) do      --collision check for bullet vs enemy and player vs enemy
for a,b in ipairs(enemy) do
if v.x < b.x+64 and v.y < b.y+64 and v.x > b.x-20 and v.y > b.y-20 then
table.remove(enemy,i)
love.event.quit()
end
end
end
end
I don't know what to do at this point, as everything else works fine. Thanks in advance.

lachlaan
Prole
Posts: 30
Joined: Sun Jun 30, 2013 7:23 pm

### Re: Collision detection problem

What's not working about it specifically? As far as I can see you're removing the enemy at position i in the table instead of position a, which could be problematic. It should still quit though if it triggers. The question is does it throw an error at all, and also how is the player position saved, and is the player info saved in a table with the format the ipairs iterator expects? The table thing could helped, making the player a variable in a table you iterate through. As well as deleting the right enemy if you care about that.

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

### Re: Collision detection problem

If you want to remove elements from a table during iteration, you have to iterate in reverse:

Code: Select all

for i = #list, 1, -1 do
if some condition then
table.remove(list, i)
end
end

PGUp
Party member
Posts: 105
Joined: Fri Apr 21, 2017 9:17 am

### Re: Collision detection problem

Spot it! Look at your code again.. it should be table.remove(enemy, a) instead of table.remove(enemy, i) in collision check between player and enemy, since the variable for the index is a, Also iterate backward so you won't see the glitchy enemy movement
-

chingydongy
Prole
Posts: 5
Joined: Sat Jan 20, 2018 4:56 pm

### Re: Collision detection problem

Well, after going through all of your guys advice, I looked at my player.lua, where the player table isn't inserted in the same way as the bullets and the enemies are through said tables (the player was declared as a player = {x,y,w,h}, not as player = {} with a table.insert() afterwards). Of course, this meant that I would have to make the whole for i,v in ipairs(player) thing go all around the code where the player.x or player.y was and replace with v. Now there's proper collision detection and the game shuts off when I hit one. Thanks again everyone

### Who is online

Users browsing this forum: No registered users and 130 guests