Page 1 of 2

Simple collision detection without Box2D

Posted: Sat Nov 13, 2010 9:58 pm
by Taehl
So, in my current project, I'm working up a basic collision system to stop players from walking through tiles. Tiles are stored in format of tiles[z][x][y] = tile_type. I do player movements like this:

Code: Select all

local p = player
local mx, my, hit = 0, 0, false
local speed = kshift and 0.1 or 0.05	-- kw, ka, ks, kd, and kshift are keyboard buttons
if kw then mx = mx-speed my = my-speed end
if ks then mx = mx+speed my = my+speed end
if ka then my = my-speed mx = mx+speed end
if kd then my = my+speed mx = mx-speed end
if (kw or ks) and (ka or kd) then mx, my = mx/2, my/2 end	-- Diagonal movement isn't faster
p.z, p.x, p.y = trace(p.z,p.z, p.x,p.x+mx, p.y,p.y+my)

function trace(sz,dz, sx,dx, sy,dy)
	local dist = math.dist(sx,dx, sy,dy, sz,dz)
	if dist <= 0 then return sz, sx, sy end
	local ltz, ltx, lty = sz, sx, sy
	for i=math.min(1, dist), dist, math.min(1, dist) do
		local tz = math.round((sz*(dist-i) + dz*i)/dist)
		local tx = math.round((sx*(dist-i) + dx*i)/dist)
		local ty = math.round((sy*(dist-i) + dy*i)/dist)
		if tiles[tz] then if tiles[tz][tx] then if tiles[tz][tx][ty] then
			if dist < 1 then return sz, sx, sy, true end
			return ltz, ltx, lty, true
		end end end
		ltz, ltx, lty = tz, tx, ty
	end
	return dz, dx, dy
end
This works quite well, except for two problems, one big and one small.
1) If you have two tiles which share a corner, the player can, if perfectly aligned, walk between them.
2) You can't "slide" along walls like you can in other games, which makes the walls "feel sticky".

I figure the way to solve #1 is to make the player have a collision radius (whereas it's currently just a point). Is anyone good enough with math to know how I can implement this?

Re: Simple collision detection without Box2D

Posted: Sat Nov 13, 2010 10:31 pm
by zac352
If I didn't read that wrong, you're trying to make a platformer where all the objects are nonrotated squares, correct?
You need to check collisions for both the x and y. If there is a collision, either bounce your player or stop them on that axis, otherwise, apply a friction coefficient.

Code: Select all

function checkCollision(x1,y1,w1,h1,x2,y2,w2,h2)
local x=false
if x2>x1 and x2<x1+w1 or x2+w2>x1 and x2+w2<x1+w1 then --check against x
x=true
end
local y=false
if y2>y1 and y2<y1+h1 or y2+h2>y1 and y2+h2<y1+h1 then --check against y
y=true
end
return x,y
end
----------------------------------
--Somewhere in love.update:
----------------------------------
for _,v in pairs(myObjects) do --generic loop
local x,y=checkCollision(myX,myY,mySizeX,mySizeY,v.x,v.y,v.w,v.h) --for your situation, you'll need to rewrite this
if x then
myVX=0 --stop player on x
--myVX=-myVX --bounce player instead?
end
if y then
myVY=0 --stop player on y
--myVY=-myVY --bounce player instead?
end
end --/loop
I hope this clarifies things for you. :awesome:

Re: Simple collision detection without Box2D

Posted: Sat Nov 13, 2010 10:33 pm
by thelinx
zac, please start indenting your code.

Re: Simple collision detection without Box2D

Posted: Sat Nov 13, 2010 10:37 pm
by zac352
thelinx wrote:zac, please start indenting your code.
Pressing tab highlights the preview button. There is a way of overriding it, but that's for whoever maintains this site. :P

Re: Simple collision detection without Box2D

Posted: Sat Nov 13, 2010 10:40 pm
by thelinx
Do you write all your code that you dump in every other post in the reply view?

Re: Simple collision detection without Box2D

Posted: Sat Nov 13, 2010 10:42 pm
by zac352
thelinx wrote:Do you write all your code that you dump in every other post in the reply view?
... Maybe. :)

Re: Simple collision detection without Box2D

Posted: Sat Nov 13, 2010 11:02 pm
by Robin
zac352 wrote:
thelinx wrote:Do you write all your code that you dump in every other post in the reply view?
... Maybe. :)
Oh god. I can picture you programming. Typing everything in the reply box on the forums, pressing Preview, copying the resulting text, pasting it in an empty Word document, saving that as plain text and then running it...

Re: Simple collision detection without Box2D

Posted: Sat Nov 13, 2010 11:09 pm
by Taehl
zac... Did you completely ignore the code I posted? Your code is only 2D, for starters...

Re: Simple collision detection without Box2D

Posted: Sat Nov 13, 2010 11:13 pm
by zac352
Taehl wrote:zac... Did you completely ignore the code I posted? Your code is only 2D, for starters...
Oh wait... Ah, well. Same rule applies. :|

Re: Simple collision detection without Box2D

Posted: Sat Nov 13, 2010 11:21 pm
by Taehl
What same rule? Your code talks about widths and heights and positions... Not a uniformly-sized, grid-aligned tile system.