Page 1 of 2
Player-enemy collision (I'm seriously stumped! : update)
Posted: Sat Aug 04, 2012 1:29 am
by GungnirDev
I need to make the enemies collide with the player and (for now) destroy the the player. I may add a health system later. I tried using the same script as I used for the bullet-enemy collision for the enemy-player collision but to no avail. The bullet code I used is under ship.lua. Nothing I've tried works or even changes, the enemies just pass right through. Please help.
Also, I'd like to know how I can spawn more enemies once there are no enemies on the screen.
Re: Player-enemy collision (I'm seriously stumped!)
Posted: Sat Aug 04, 2012 4:32 pm
by flashkot
why you declare
CheckCollision() function within
love.update() ?
Move its declaration somether outside
love.update(). Better place it before all
require comands in main.lua
and watch your code identation! Some times it is hard to tell where your functions ends and where starts next function.
And check your hitboxes. They do not match images you use for player and enemies.
If change all this and put code where it should be, yours
CheckCollision() works pretty well and collides player with enemies.
Also delete enemies when wey get out of screen. Then you can check if there is no one to fight (
if # enemies = 0 then) and add another foes.
Re: Player-enemy collision (I'm seriously stumped! : update)
Posted: Sun Aug 05, 2012 9:04 am
by GungnirDev
OK, I put the BoundingBox in main.lua like you suggested but it's still not working. I've having a hard time wrapping my head around collision, I can't do much of anything with this function cause I don't know why it works (or doesn't, in my case)
I did try playing with the numbers and that at least makes me somewhat understand exactly what the collision function does, but then I tried changing the width and height of the collision functions to 100s to see if that would work (it didn't). Then I tried changing the v.x's to direct player values and taking out the ipairs function to see if a direct approach would work (it didn't) and, since I thought that maybe it would help if the result was a simpler thing that I had already made happen, I changed the desired "result" to love.event.quit() (because I can do that with the escape function) and that didn't work either.
I'm not lazy...just slow...
I'm trying though.
Code: Select all
if CheckCollision(player.x,player.y,100,100,enemy.x,enemy.y,100,100) then
love.event.quit()
I'm sure there's a million things wrong with this code.
Re: Player-enemy collision (I'm seriously stumped! : update)
Posted: Sun Aug 05, 2012 9:49 am
by flashkot
Again - watch your code indentation!
I love Python for its strict indentation, very nice option for programming language you learn first.
So, take a look at your
ship.lua file. You placed collision detection in lines 72-74. Very likely that your problem is what you think, what this is the end of
player.update() function. It looks so by indentation of blocks on lines 64-70 and by
end at line 76.
But indentation is wrong. You make a trap for yourself.
end on line 76 just closes
for opened on line 43. And this
for block is used to process bullets. So, no bullets - no collision detection.
Re: Player-enemy collision (I'm seriously stumped! : update)
Posted: Sun Aug 05, 2012 10:00 am
by flashkot
One more trick i like:
put comment on
end for very big blocks. It helps to track where this
end belongs to
Code: Select all
function player.update(dt)
-- ... many many pages of very complex code...
end -- function player.update
or
Code: Select all
for i,v in ipairs(player.shots) do
-- ... many many pages of very complex code...
end -- bullets processing
Re: Player-enemy collision (I'm seriously stumped! : update)
Posted: Sun Aug 05, 2012 10:01 am
by ivan
thesmeagle wrote:OK, I put the BoundingBox in main.lua like you suggested but it's still not working. I've having a hard time wrapping my head around collision, I can't do much of anything with this function cause I don't know why it works (or doesn't, in my case)
It's much simpler than you think.
Imagine two rectangles (r1 and r2):
Code: Select all
-----------
----------- | |
| | | (r2) |
| (r1) | | |
| | -----------
-----------
To figure out if they are overlapping you have to check a couple of simple conditions:
is the RIGHT side of r1 LESS than the LEFT side of r2
OR
is the LEFT side of r1 GREATER than the RIGHT side of r2
If any of these two conditions is TRUE the two boxes are NOT intersecting.
That's all there is to it! ...well almost, we have to check the Y axis as well, but it's the same principle.
To put in pseudo code:
Code: Select all
if r1.RIGHT < r2.LEFT or r1.LEFT > r2.RIGHT then
return false -- no collision
end
if r1.BOTTOM < r2.TOP or r1.TOP > r2.BOTTOM then
return false -- no collision
end
return true -- in any other case they must be intersecting
Most of the confusion is caused by the different types of bounding box representations.
If I remember correctly BoundingBox.lua accepts an X and Y position for the TOP-LEFT corner of each rectangle along with their WIDTH/HEIGHT.
You could easily write your own version that accept LEFT, TOP, RIGHT, BOTTOM coords for each rectangle.
Re: Player-enemy collision (I'm seriously stumped! : update)
Posted: Sun Aug 05, 2012 10:06 am
by ivan
thesmeagle wrote:OK, I put the BoundingBox in main.lua like you suggested but it's still not working. I've having a hard time wrapping my head around collision, I can't do much of anything with this function cause I don't know why it works (or doesn't, in my case)
It's much simpler than you think.
Imagine two rectangles (r1 and r2):
Code: Select all
-----------
----------- | |
| | | (r2) |
| (r1) | | |
| | -----------
-----------
To figure out if they are overlapping you have to check a couple of simple conditions:
is the RIGHT side of r1 LESS than the LEFT side of r2
OR
is the LEFT side of r1 GREATER than the RIGHT side of r2
If any of these two conditions is TRUE the two boxes are NOT intersecting.
That's all there is to it! ...well almost, we have to check the Y axis as well, but it's the same principle.
To put in pseudo code:
Code: Select all
if r1.RIGHT < r2.LEFT or r1.LEFT > r2.RIGHT then
return false -- no collision
end
if r1.BOTTOM < r2.TOP or r1.TOP > r2.BOTTOM then
return false -- no collision
end
return true -- in any other case they must be intersecting
Most of the confusion is caused by the different types of bounding box representations.
If I remember correctly BoundingBox.lua accepts an X and Y position for the TOP-LEFT corner of each rectangle along with their WIDTH/HEIGHT.
You could easily write your own version that accept LEFT, TOP, RIGHT, BOTTOM coords for each rectangle.
Re: Player-enemy collision (I'm seriously stumped! : update)
Posted: Sun Aug 05, 2012 11:30 am
by Santos
You might find this helpful to understand rectangle intersection:
http://silentmatt.com/rectangle-intersection/
Try moving the rectangles around and see what happens!
Consider having a debugging mode which, when on, draws rectangles around hitboxes and maybe displays other information. To do this, set up a boolean variable in
love.load...
Code: Select all
function love.load()
debugging = true
You can then draw helpful things if debugging is
true...
ship.lua
Code: Select all
function player.draw()
love.graphics.setColor(255,230,255)
love.graphics.draw(fighter, player.x, player.y)
if debugging then
love.graphics.rectangle('line', player.x, player.y, player.width, player.height)
end
end
foe.lua
Code: Select all
function foe.draw()
love.graphics.setColor(255,255,255,255)
for i,v in ipairs(enemies) do
love.graphics.draw (wolv, v.x, v.y)
if debugging then
love.graphics.rectangle('line', v.x, v.y, v.width, v.height)
end
end
end
To quit the game when the player touches an enemy, try this:
- Loop through all the enemies
- Check for collisions between the player and the current enemy in the loop
You can do this by putting this right at the start of
player.update:
Code: Select all
for _, enemy in ipairs(enemies) do
if CheckCollision(player.x, player.y, player.width, player.height, enemy.x, enemy.y, enemy.width, enemy.height) then
love.event.quit()
end
end
Re: Player-enemy collision (I'm seriously stumped! : update)
Posted: Mon Aug 06, 2012 9:29 am
by GungnirDev
Ok Santos, your code worked which is pretty much just how I thought it would. I think the problem wasn't me not getting collision but rather me not looping through the right objects. Good concept, bad coding, I think. But thanks!
IDK about the respawning enemies though. I tried putting the update function in foe.update but the enemies won't spawn.
I figured that the problem might be that not all the enemies are getting removed, but I have the mark and remove function in both foe.update and ship.update so it should remove the enemies, right?
I cleaned up the code a little, and also I made music! In GarageBand. It's kinda fail but it's original and it plays OK. At least sound is easy to do in love...
Re: Player-enemy collision (I'm seriously stumped! : update)
Posted: Mon Aug 06, 2012 10:28 am
by Santos
I like the music!
First of all, it would be really useful to know how many enemies there are, that way you can see if they are being removed or not:
Code: Select all
function foe.draw()
love.graphics.print('#enemies: '..#enemies, 10, 10)
Hmm, it seems like they're not. Next step: checking the code which removes enemies!
Code: Select all
-- mark enemies that are not visible for removal
if v.y < 0 then
table.insert(remEnemy, i)
end
In LÖVE, a y coordinate of 0 is the top of the screen, so this is actually checking if the enemy is above the screen! Let's fix this:
Code: Select all
-- mark enemies that are not visible for removal
if v.y > love.graphics.getHeight() then
table.insert(remEnemy, i)
end
Now we can see from the number of enemies that they are actually being removed. But no new enemies are being created...
Code: Select all
if # enemies == 0 then
for i=0,4 do
enemy = {}
enemy.width = 40
enemy.height = 20
enemy.x = i * (enemy.width + 100) + 100
enemy.y = i * (enemy.height + 50) + 100
end
end
The
enemy table is being made... but it's not being inserted into the
enemies table.
Code: Select all
if # enemies == 0 then
for i=0,4 do
enemy = {}
enemy.width = 40
enemy.height = 20
enemy.x = i * (enemy.width + 100) + 100
enemy.y = i * (enemy.height + 50) + 100
table.insert(enemies, enemy)
end
end
And it works!