Page 1 of 1

Bounding Box not working

Posted: Fri Nov 09, 2018 10:21 am
by StormtrooperCat
I am trying to create a 2-player velocity test, where each surface has a different speed, but when i added bounding box (which I have used before and worked fine) it collides only with the top left corner of the player, rather than how it should, and I cannot work out what is wrong.

I have attached a LOVE file.

Thanks for any help.

P.S. The bounding box was copied directly from the LOVE wiki, and i did not type it up myself.

Re: Bounding Box not working

Posted: Fri Nov 09, 2018 12:21 pm
by pgimeno
The function checkTile scans tiles until it finds one that the player is overlapping. But when the player is overlapping several tiles, the first one that is detected is the one returned by checkTile(). Consider this situation:
Duck-problem.png
Duck-problem.png (1.41 KiB) Viewed 4180 times
In that case, tile 1 will be returned by checkTile, because it's the first in left-to-right, up-to-down order that the player is overlapping, even though the player is penetrating a wall (tiles 2 and 4). Therefore, the wall won't be detected until the left side of the player is fully inside it, because checkTile won't return wall until the first tile the player is overlapping is a wall.

On a side note, your method of detecting overlap is very slow. With some arithmetic you should be able to detect the same thing without having to loop over every tile.

Re: Bounding Box not working

Posted: Sat Nov 10, 2018 9:55 am
by StormtrooperCat
Thank you very much for your reply. I will try and implement that soon.

What suggestions do you have to cut down the collision time?

Re: Bounding Box not working

Posted: Sat Nov 10, 2018 11:16 am
by pgimeno
Well, if the bounding box of your player has its top left corner at x and y, and a width and height of w and h, you can determine the tile where each corner is, as follows:

Code: Select all

  local top_left_tile_x = math.floor(x / tile_size)
  local top_left_tile_y = math.floor(y / tile_size)
  local bottom_right_tile_x = math.floor((x + w) / tile_size)
  local bottom_right_tile_y = math.floor((y + h) / tile_size)
  local top_right_tile_x = bottom_right_tile_x
  local top_right_tile_y = top_left_tile_y
  local bottom_left_tile_x = top_left_tile_x
  local bottom_left_tile_y = bottom_right_tile_y
Then with e.g. grid[top_left_tile_x][top_left_tile_y] you have the tile under the top left corner of the player, and so on.

For terrain, I'd say to check all four tiles and calculate the slowest of them (using math.max or math.min as appropriate).

For walls, if your player is going right, you need to check one of the right corners; if it's going up, one of the top corners, and so on.

edited to fix typo: hace -> have

Re: Bounding Box not working

Posted: Sat Nov 10, 2018 10:42 pm
by StormtrooperCat
Thank you very much (again) I implemented your ideas, and it was actually a very easy fix for the collision (i just put the grid type inside the function). I also used your method to cut down the amount it has to check.


Thanks! :awesome:

Re: Bounding Box not working

Posted: Sun Nov 11, 2018 1:15 am
by pgimeno
It seems to work pretty well, nice work!