Page 1 of 1

Noob on collision detection

Posted: Wed Apr 27, 2011 2:30 pm
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.

Re: Noob on collision detection

Posted: Wed Apr 27, 2011 3:06 pm
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.

Re: Noob on collision detection

Posted: Thu Apr 28, 2011 3:05 am
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. ;)

Re: Noob on collision detection

Posted: Thu Apr 28, 2011 3:54 am
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

Re: Noob on collision detection

Posted: Thu Apr 28, 2011 11:25 am
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.

Re: Noob on collision detection

Posted: Thu Apr 28, 2011 1:24 pm
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

Re: Noob on collision detection

Posted: Thu Apr 28, 2011 3:12 pm
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.

Re: Noob on collision detection

Posted: Thu Apr 28, 2011 3:21 pm
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. :)

Re: Noob on collision detection

Posted: Thu Apr 28, 2011 5:18 pm
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)

Re: Noob on collision detection

Posted: Mon May 02, 2011 1:30 pm
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