Noob on collision detection

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
mrpoptart
Prole
Posts: 17
Joined: Mon Apr 25, 2011 5:31 am

Noob on collision detection

Post by mrpoptart »

Hello all. I have read these forums, and read the wiki on collision detection. My main problem is understanding how to turn these circles, and rectangles into the images in my game.

If any one knows a better tutorial, that would be awesome.

I need detection for certain tiles on my map, the enemies, and the bullets for both the player and the enemy.

I tried to grasp the collision detection with hardonCollider, and love Physics. But alas, it seems that i am far to newish to understand.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Noob on collision detection

Post by Robin »

Collision detection and handling physics in general is complicated business. I'd suggest hardonCollider, although I do not know your specific situation.

Are you saying your game is tile-based?

Perhaps we might be able to help you in a better way if you describe your specifics in more detail.
Help us help you: attach a .love.
lesslucid
Prole
Posts: 20
Joined: Sun Mar 20, 2011 8:25 am

Re: Noob on collision detection

Post by lesslucid »

How do you turn circles and rectangles into the images in your game? It won't give you perfect "per pixel" detection, but you just have a rectangle sitting roughly over the area of the image you want to be "collidable" and use that as your basis. So, a perfectly square bullet that's 5 pixels by 5 pixels can just use the x & y values of the bullet itself and 5 as the width and height of its rectangle. An enemy ship with various "bits" sticking out you might want to add 3 pixels to its x & y and reduce its width and height by 6 (for example) and then use a bit of code like this:

Code: Select all

function collideCheck(x1, y1, w1, h1, x2, y2, w2, h2) -- the x, y, w, and h values of objects 1 and 2
	local collided = 0
	if (x1 > x2 and x1 < x2 + w2) or (x1 + w1 > x2 and x1 + w1 < x2 + w2) then
		if (y1 > y2 and y1 < y2 + h2) or (y1 + h1 > y2 and y1 + h1 < y2 + h2) then
			collided = 1
		end
	end
	return collided
end
...to tell you if it collides with something or not. This is a rough method but has the advantage of being easy to do. ;)
User avatar
Jasoco
Inner party member
Posts: 3727
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Noob on collision detection

Post by Jasoco »

lesslucid wrote:How do you turn circles and rectangles into the images in your game? It won't give you perfect "per pixel" detection, but you just have a rectangle sitting roughly over the area of the image you want to be "collidable" and use that as your basis. So, a perfectly square bullet that's 5 pixels by 5 pixels can just use the x & y values of the bullet itself and 5 as the width and height of its rectangle. An enemy ship with various "bits" sticking out you might want to add 3 pixels to its x & y and reduce its width and height by 6 (for example) and then use a bit of code like this:

Code: Select all

function collideCheck(x1, y1, w1, h1, x2, y2, w2, h2) -- the x, y, w, and h values of objects 1 and 2
	local collided = 0
	if (x1 > x2 and x1 < x2 + w2) or (x1 + w1 > x2 and x1 + w1 < x2 + w2) then
		if (y1 > y2 and y1 < y2 + h2) or (y1 + h1 > y2 and y1 + h1 < y2 + h2) then
			collided = 1
		end
	end
	return collided
end
...to tell you if it collides with something or not. This is a rough method but has the advantage of being easy to do. ;)
This is more compact:

Code: Select all

function overlap(x1,y1,w1,h1, x2,y2,w2,h2)
  return not (x1+w1 < x2  or x2+w2 < x1 or y1+h1 < y2 or y2+h2 < y1)
end
And this one works for a single point inside a box:

Code: Select all

function inside(x1,y1, x2,y2,w2,h2)
  return not (x1 < x2  or x2+w2 < x1 or y1 < y2 or y2+h2 < y1)
end
And you can use this one to find collisions of a single point with a circle: (By checking if the distance is less than the radius of the circle)

Code: Select all

function distanceFrom(x1,y1,x2,y2) 
  return math.sqrt((x2 - x1) ^ 2 + (y2 - y1) ^ 2) 
end
User avatar
vrld
Party member
Posts: 917
Joined: Sun Apr 04, 2010 9:14 pm
Location: Germany
Contact:

Re: Noob on collision detection

Post by vrld »

mrpoptart wrote:Hello all. I have read these forums, and read the wiki on collision detection. My main problem is understanding how to turn these circles, and rectangles into the images in my game.
Just draw the image where the rectangle or circle would be and don't draw the shapes.
I have come here to chew bubblegum and kick ass... and I'm all out of bubblegum.

hump | HC | SUIT | moonshine
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Noob on collision detection

Post by ivan »

Jasoco wrote:

Code: Select all

function overlap(x1,y1,w1,h1, x2,y2,w2,h2)
  return not (x1+w1 < x2  or x2+w2 < x1 or y1+h1 < y2 or y2+h2 < y1)
end
I'm not sure but I don't think this code would work correctly. A rect vs rect overlap test should be:

Code: Select all

function overlapRectRect (x1, y1, hw1, hh1, x2, y2, hw2, hh2)
  return not (x1-hw1>x2+hw2 or x1+hw1<x2-hw2 or y1-hh1>y2+hh2 or y1+hh1<y2-hh2)
end
Jasoco wrote:And you can use this one to find collisions of a single point with a circle: (By checking if the distance is less than the radius of the circle)

Code: Select all

function distanceFrom(x1,y1,x2,y2) 
  return math.sqrt((x2 - x1) ^ 2 + (y2 - y1) ^ 2) 
end
Also, the square root operation can be avoided like so:

Code: Select all

function overlapCircleCircle ( x1, y1, r1, x2, y2, r2) 
  local dx = x2-x1
  local dy = y2-y1
  local radii = r1 + r2
  return dx * dx + dy * dy < radii * radii
end
Last edited by ivan on Mon May 02, 2011 1:31 pm, edited 1 time in total.
mrpoptart
Prole
Posts: 17
Joined: Mon Apr 25, 2011 5:31 am

Re: Noob on collision detection

Post by mrpoptart »

Robin wrote:Collision detection and handling physics in general is complicated business. I'd suggest hardonCollider, although I do not know your specific situation.

Are you saying your game is tile-based?

Perhaps we might be able to help you in a better way if you describe your specifics in more detail.

i am sorry i did not explain better robin. My game is tile based, each image is 32x32 pixles, even my enemy and my player tank.

I would like for the game to be able to collide with a certain tile on my map each time it tries to go across it, as well as for the bullets to hit the enemy, enemy bullets to hit the player, and the player and enemy tanks to be able to hit each other, instead of just go right through each other.

example of the tiles:

right now i am using two tiles in my map. A brown tile, or dirt, and a green tile, or grass. I would like the tank to be able to move on the dirt tiles and not be able to move on the grass tiles. This way i can make a dirt road kind of like a maze for the players to have to weave in and out of to be able to encounter the enemy tanks.

I read on the forums that someone had a way of doing this tile collision, by simply adding a variable to their tiles, that says if its walkable or not, but was unable to find any sample code, because that would be awesome.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Noob on collision detection

Post by Robin »

Okay. Tile-based collision is a field apart, really. HC and Box2D aren't really fit for that.
mrpoptart wrote:I read on the forums that someone had a way of doing this tile collision, by simply adding a variable to their tiles, that says if its walkable or not, but was unable to find any sample code, because that would be awesome.
That is quite easy to do. It depends on your exact implementation, but it will be quite straightforward. So that's a good idea.

It won't work for bullets, of course. You'll have to figure out something else for that. We might be able to help you with it, though. :)
Help us help you: attach a .love.
User avatar
Jasoco
Inner party member
Posts: 3727
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Noob on collision detection

Post by Jasoco »

ivan wrote:
Jasoco wrote:

Code: Select all

function overlap(x1,y1,w1,h1, x2,y2,w2,h2)
  return not (x1+w1 < x2  or x2+w2 < x1 or y1+h1 < y2 or y2+h2 < y1)
end
I'm not sure but I don't think this code would work correctly. A rect vs rect overlap test should be:

Code: Select all

function overlapRectRect (x1, y1, w1, h1, x2, y2, w2, h2)
  return not (x1-w1>x2+w2 or x1+w1<x2-w2 or y1-h1>y2+h2 or y1+h1<y2-h2)
end
Not my code. One of the forum regulars here gave it to me to replace the code I used before that went the
long" way and it has never not worked for me. I use it all the time.

This is what I used to use:

Code: Select all

return (x2 >= x1 and x2 <= x1+w1) and (y2 >= y1 and y2 <= y1+h1) or
	(x2+w2 >= x1 and x2+w2 <= x1+w1) and (y2 >= y1 and y2 <= y1+h1) or
	(x2 >= x1 and x2 <= x1+w1) and (y2+h2 >= y1 and y2+h2 <= y1+h1) or
	(x2+w2 >= x1 and x2+w2 <= x1+w1) and (y2+h2 >= y1 and y2+h2 <= y1+h1) or
	(x1 >= x2 and x1 <= x2+w2) and (y1 >= y2 and y1 <= y2+h2) or
	(x1+w1 >= x2 and x1+w1 <= x2+w2) and (y1 >= y2 and y1 <= y2+h2) or
	(x1 >= x2 and x1 <= x2+w2) and (y1+h1 >= y2 and y1+h1 <= y2+h2) or
	(x1+w1 >= x2 and x1+w1 <= x2+w2) and (y1+h1 >= y2 and y1+h1 <= y2+h2)
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Noob on collision detection

Post by ivan »

Jasoco wrote:Not my code. One of the forum regulars here gave it to me to replace the code I used before that went the
long" way and it has never not worked for me. I use it all the time
I think I understand now.
The reason why the code works is because of your rect implementation.
In your code:
x1, y1 is the top, left corner of the rect and
w1, h1 is the width and height of the rect
In my code:
x1, y1 is the center point of the rect and
w1, h1 is the half-width and half-height of the rect
There is a third alternative for representing rects which simplifies the intersection code even more:
l1, t1 is the top, left corner of the rect and
b1, r1 is the bottom, right corner of the rect

Code: Select all

function intersectRectRect ( l1, t1, r1, b1, l2, t2, r2, b2 )
   return not ( l1 > r2 or r1 < l2 or t1 > b2 or b1 < t2 )
end
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 8 guests