Page 1 of 2

Collision Detection Not Working?

Posted: Sun Dec 20, 2015 2:53 am
by TheNiny
Hello! I am really new to Love2d and need some help. So, the problem is whenever I launch my game everything works properly, except when I shoot the enemy (red square) nothing happens!
The code that I need help debugging is in player.lua at line 106 and the CheckCollision function is in collide.lua.
You can download the project here. Any help... well.. helps! Thanks!

~Niny

Re: Collision Detection Not Working?

Posted: Sun Dec 20, 2015 6:33 pm
by pgimeno
'enemy' is not a sequence, it's a regular table.

I mean, you don't have enemy[1].x, enemy[1].y... enemy[2].x, enemy[2].y...

Instead, you have enemy.x, enemy.y...

Therefore, this loop does nothing:

Code: Select all

    for i, enemy in ipairs(enemy) do
Given your naming scheme, commenting out that line and its corresponding end suffices. It then crashes because bullet does not have .w or .h fields. Same problem: you have bullet.w and bullet.h but not bullet.w, bullet.h, and since you chose the same name for the loop variable, it's not visible inside the loop.

I'd advise you to use plurals for sequences: enemies, bullets. Then, enemies[1] is the first enemy; bullets[1] is the first bullet, and so on. When you loop over them, you can use singular: for index, bullet in ipairs(bullets) do ... end. If you were using that naming scheme you could take advantage of it and write: if CheckCollision(bullet.x, bullet.y, bullets.w, bullets.h...)

Re: Collision Detection Not Working?

Posted: Mon Dec 21, 2015 4:52 pm
by TheNiny
Ok, I get what you are saying, but I don't know how to put it into code. So what I did is made it a little simpler and didn't use an ipairs based loop. Here is what it looks like now.

Code: Select all

function player.detect()
 
 for j = #bullet, 1, -1 do
      if CheckCollision(bullet[j].x, bullet[j].y, bullet.w, bullet.h, enemy.x, enemy.y, enemy.w, enemy.h) then
        table.remove(bullet, j)
    end
  end
  
end
So when the bullet hits the enemy, the bullet disappears. Is there a way to make a enemy disappear also?

Re: Collision Detection Not Working?

Posted: Mon Dec 21, 2015 8:18 pm
by pgimeno
TheNiny wrote:So when the bullet hits the enemy, the bullet disappears. Is there a way to make a enemy disappear also?
If you only have one, then you can have a status flag that indicates if there's an enemy or not, and not draw it or check collisions if there isn't.

Otherwise you need to make an 'enemies' sequence with enemies[1], enemies[2], ... enemies[#enemies].

Re: Collision Detection Not Working?

Posted: Tue Dec 22, 2015 4:20 am
by TheNiny
Ok, yes I'm a n00b, but can you show me what that code would look like?

Re: Collision Detection Not Working?

Posted: Tue Dec 22, 2015 4:30 am
by pgimeno
Basically, make a table with the enemy data, e.g. enemy = {x = 200, y = 200, w = 50, h = 50...}, and then assign enemies[#enemies+1] = enemy. Then the loop you had at the beginning should probably work (amended adequately according to the bullets fix and the plural name of the table).

Re: Collision Detection Not Working?

Posted: Tue Dec 22, 2015 4:46 am
by TheNiny
I have updated the loop to something that is more understandable for me. The code now looks like this

Code: Select all

function player.detect()
 
  for j = #bullet, 1, -1 do
      if CheckCollision(bullet[j].x, bullet[j].y, bullet.w, bullet.h, enemy.x, enemy.y, enemy.w, enemy.h) then
        table.remove(bullet, j)
      end
    end
  for i = #enemy, 1, -1 do
    if CheckCollision(bullet.x, bullet.y, bullet.w, bullet.h, enemy[i].x, enemy[i].y, enemy.w, enemy.h) then
      table.remove(enemy, i)
      print("Detected")
    end
  end
end

And it deletes the bullet, but doesn't do anything to the enemy. It doesn't even print what I told it to (print("Detected")) I'm sorry I'm so bad at this ad I'm probably bothering you, but thanks for all the help! (The link has been updated if you want to take a look)

Re: Collision Detection Not Working?

Posted: Tue Dec 22, 2015 4:56 pm
by Beelz
That's because you delete the bullet after the first collision check. Then when you check the enemies, it will always be false. Just remove them together.

Code: Select all

for b = #bullets, 1, -1 do
    for e = #enemies, 1, -1 do
        if CheckCollision(b.x, b.y, bullet.w, bullet.h, e.x, e.y, enemy.w, enemy.h) then
            table.remove(bullets, b)
            table.remove(enemies, e)
        end
    end
end

Re: Collision Detection Not Working?

Posted: Tue Dec 22, 2015 5:47 pm
by TheNiny
Welp... I did that exact thing. And it still doesn't work! I honestly think that I might just give up right about now. :?

Re: Collision Detection Not Working?

Posted: Tue Dec 22, 2015 6:00 pm
by pgimeno
If you want multiple enemies, your enemies table should be a sequence of tables. A table and a sequence are the same thing, except that a sequence has consecutive numeric indices starting at 1 (and it can have other fields as well, like tables do), which improves performance in Lua.

This is what a sequence of tables looks like (schematic): { {data for enemy 1}, {data for enemy 2}, ... }

The outer { } correspond to the sequence; the inner {}'s correspond to each enemy data.

Your enemy.load() function loads the enemy data into the top table, so instead you have: { data for enemy 1 }

That prevents you from having multiple enemies, and doesn't correspond to how you're treating it in the collision detection loop. The way you treat the data must correspond with the way you organize the data. Only changing the loop won't work if you don't change how you store the data.

You need to rewrite your enemy.load() so that it creates a new table with the data and puts it in the main enemies sequence.

Similarly, enemy.draw, enemy.physics... need to loop over every enemy in order to update them all, once you put them in sequences. Now it works because you only have one and it is not inside a sequence.